Page MenuHomec4science

No OneTemporary

File Metadata

Created
Sun, Jun 30, 05:37
This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/.gitignore b/.gitignore
index 7d1a224..0b0ce66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,77 +1,75 @@
# git-ls-files --others --ignored
# Lines that start with '#' are comments.
# Working files 2015
# Need to clean up bin/ and build/ for git
bin/
-build/
-build-mar14/
-build-new/
-buildqt/
-buildvc/
src/qhulltest/qhulltest-mini.pro
src/qhulltest/RoadTest.h.cpp
# Backup and data files
eg/eg.*
*~
*.bak
*.off
+*.tmp
*.x
x.*
r
x
x?
r?
# patch results
*.rej
# Build products
tmp/*
-build-cmake/*
+build-*/
build/Debug/*
build/moc/*
build/qhulltest/*
build/Release/*
build/cmake_install.cmake
build/CMakeCache.txt
build/CMakeFiles
build/install_manifest.txt
build/Makefile*
+build/Testing/*
+build/CTest*
build/*/Makefile*
build/*/object_script*
build/*/Release/*
build/*/Debug/*
build/*/MinSizeRel/*
build/*/RelWithDebInfo/*
-lib
+lib/
*.a
*.dll
*.idb
*.lib
*.exe
*.o
*.md5sum
# Qt files
*.pro.user
# DevStudio files
*.bsc
*.ncb
*.pdb
*.suo
*.user
*.ilk
# CVS files
CVS/*
*/CVS/*
*/*/CVS/*
*/*/*/CVS/*
*.cvsignore
# Other files
working/
diff --git a/Announce.txt b/Announce.txt
index ac8e052..51c9d0c 100644
--- a/Announce.txt
+++ b/Announce.txt
@@ -1,51 +1,51 @@
- Qhull 2012.1 2012/02/18
+ Qhull 2015.0.2 2015/08/30
http://www.qhull.org
git@gitorious.org:qhull/qhull.git
http://packages.debian.org/sid/libqhull5 [out-of-date]
http://www6.uniovi.es/ftp/pub/mirrors/geom.umn.edu/software/ghindex.html
http://www.geomview.org
http://www.geom.uiuc.edu
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@gitorious.org:qhull/qhull.git
http://packages.debian.org/sid/libqhull5 [out-of-date]
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/CMakeLists.txt b/CMakeLists.txt
index 98dbc70..6012150 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,432 +1,581 @@
# 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 <build/install_manifest.txt
#
-# To build Qhull Visual Studio projects, run cmake twice
-# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 8 2005" .. && cmake ..
+# To build Qhull with Visual Studio projects, run cmake twice
+# To install bin/doc/include/lib in the current directory
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012" .. && cmake -DCMAKE_INSTALL_PREFIX=.. ..
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012 Win64" .. && cmake -DCMAKE_INSTALL_PREFIX=.. ..
+# To install into Program Files/qhull
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012" .. && cmake ..
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012 Win64" .. && cmake ..
+# To build for Visual Studio 2005 and install into Program Files/qhull
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 8 2005" .. && cmake ..
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 8 2005 Win64" .. && cmake ..
# Double click build-cmake/qhull-all.sln
-# Build INSTALL for C:/Program Files/qhull
+# Build INSTALL to copy files into C:/Program Files/qhull
+#
+# Notes on Visual Studio projects
# You may need to copy bin/msvcr80.dll into C:/Program Files/qhull/bin
# If using library debug targets, please rename with '_d' (e.g., qhullstatic_d.lib)
-#
+#
# To uninstall on Windows
# Delete C:/Program Files/qhull
#
# For qhulltest, use the Qt build (src/qhull-all.pro)
#
-# Qhull ships with cmake-derived sln and proj files
-# See eg/make-vcproj.sh -- it created the first versions of these files
+# Qhull ships with cmake-derived sln and proj files for DevStudio 8 2005
# Change to relative paths
# Remove ZERO_CHECK, ALL_BUILD, and INSTALL projects
# Change targets to bin/ and lib/ directories
# Disable incremental linking and ilk files (LinkIncremental="1")
# Disable Run-Time Type Info (rtti)
# Remove src/libqhullcpp from most of the AdditionalIncludeDirectories
# Remove CMAKE_INTDIR from PreprocessorDefinitions
-# Adjust target names and destinations (e.g., lib/libqhullstatic_d.a)
+# Adjust target names and destinations (e.g., lib/libqhullstatic_rd.a)
#
-# $Id: //main/2011/qhull/CMakeLists.txt#23 $$Change: 1494 $
-# $DateTime: 2012/02/21 22:41:40 $$Author: bbarber $
+# $Id: //main/2011/qhull/CMakeLists.txt#34 $$Change: 1930 $
+# $DateTime: 2015/07/12 15:15:42 $$Author: bbarber $
project(qhull)
cmake_minimum_required(VERSION 2.6)
-# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, and qhull-warn.pri
+# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull-warn.pri
+set(qhull_VERSION2 "2015.0.2 2015/08/30") # not used, See global.c, global_r.c, rbox.c, rbox_r.c
string(REGEX REPLACE ".* ([0-9]+) .*"
- "6.3.1.\\1" qhull_VERSION "$Change: 1494 $")
-# qhull_SOVERSION: 2003 = empty, 2009 = 5 , 2010-2012 = 6
-set(qhull_SOVERSION 6)
-set(qhull_VERSION2 "2012.1 2012/02/18")
+ "7.0.2.\\1" qhull_VERSION "$Change: 1930 $")
+
+# SOVERSION -- qhull 2003 = empty, 2009 = 5, 2010-2012 = 6, 2015 (reentrant) = 7
+set(qhull_SOVERSION 7) # For SOVERSION
if(INCLUDE_INSTALL_DIR)
else()
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include)
endif()
if(LIB_INSTALL_DIR)
else()
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
endif()
if(BIN_INSTALL_DIR)
else()
set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin)
endif()
if(MAN_INSTALL_DIR)
else()
if(WIN32)
set(MAN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/man/man1)
else()
set(MAN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/man/man1)
endif()
endif()
if(DOC_INSTALL_DIR)
else()
if(WIN32)
set(DOC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/doc)
else()
set(DOC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/doc/qhull)
endif()
endif()
message(STATUS)
message(STATUS "========== qhull Build Information ==========")
-message(STATUS "Build Version: ${qhull_VERSION}")
+message(STATUS "Build Version: ${qhull_VERSION}")
message(STATUS "Install Prefix (CMAKE_INSTALL_PREFIX): ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Binary Directory (BIN_INSTALL_DIR): ${BIN_INSTALL_DIR}")
message(STATUS "Library Directory (LIB_INSTALL_DIR): ${LIB_INSTALL_DIR}")
message(STATUS "Include Directory (INCLUDE_INSTALL_DIR): ${INCLUDE_INSTALL_DIR}")
message(STATUS "Documentation Directory (DOC_INSTALL_DIR): ${DOC_INSTALL_DIR}")
message(STATUS "Man Pages Directory (MAN_INSTALL_DIR): ${MAN_INSTALL_DIR}")
message(STATUS "Build Type (CMAKE_BUILD_TYPE): ${CMAKE_BUILD_TYPE}")
message(STATUS "To override these options, add -D{OPTION_NAME}=... to the cmake command")
message(STATUS " Build the debug targets -DCMAKE_BUILD_TYPE=Debug")
message(STATUS)
message(STATUS "To build and install qhull, enter \"make\" and \"make install\"")
+message(STATUS "To smoketest qhull, enter \"ctest\"")
message(STATUS)
+
# ---------------------------------------
# Define library source files and variables
#
# Files for individual targets are defined with the target
# ---------------------------------------
# Order libqhull object files by frequency of execution. Small files at end.
+
+# Non-reentrant Qhull
set(
libqhull_HEADERS
src/libqhull/libqhull.h
src/libqhull/geom.h
src/libqhull/io.h
src/libqhull/mem.h
src/libqhull/merge.h
src/libqhull/poly.h
src/libqhull/qhull_a.h
src/libqhull/qset.h
src/libqhull/random.h
src/libqhull/stat.h
src/libqhull/user.h
)
set(
libqhull_SOURCES
src/libqhull/global.c
src/libqhull/stat.c
src/libqhull/geom2.c
src/libqhull/poly2.c
src/libqhull/merge.c
src/libqhull/libqhull.c
src/libqhull/geom.c
src/libqhull/poly.c
src/libqhull/qset.c
src/libqhull/mem.c
src/libqhull/random.c
src/libqhull/usermem.c
src/libqhull/userprintf.c
src/libqhull/io.c
src/libqhull/user.c
src/libqhull/rboxlib.c
src/libqhull/userprintf_rbox.c
${libqhull_HEADERS}
)
set(
libqhull_DOC
src/libqhull/index.htm
src/libqhull/qh-geom.htm
src/libqhull/qh-globa.htm
src/libqhull/qh-io.htm
src/libqhull/qh-mem.htm
src/libqhull/qh-merge.htm
src/libqhull/qh-poly.htm
src/libqhull/qh-qhull.htm
src/libqhull/qh-set.htm
src/libqhull/qh-stat.htm
src/libqhull/qh-user.htm
+ src/libqhull/DEPRECATED.txt
)
set(
testqset_HEADERS
src/libqhull/mem.h
src/libqhull/qset.h
)
set(
testqset_SOURCES
src/libqhull/qset.c
src/libqhull/mem.c
src/testqset/testqset.c
${testqset_HEADERS}
)
+# Reeentrant Qhull
+
+set(
+ libqhullr_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
+)
+set(
+ libqhullr_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/userprintf_r.c
+ src/libqhull_r/io_r.c
+ src/libqhull_r/user_r.c
+ src/libqhull_r/rboxlib_r.c
+ src/libqhull_r/userprintf_rbox_r.c
+ ${libqhullr_HEADERS}
+)
+
+set(
+ libqhullr_DOC
+ src/libqhull_r/index.htm
+ src/libqhull_r/qh-geom_r.htm
+ src/libqhull_r/qh-globa_r.htm
+ src/libqhull_r/qh-io_r.htm
+ src/libqhull_r/qh-mem_r.htm
+ src/libqhull_r/qh-merge_r.htm
+ src/libqhull_r/qh-poly_r.htm
+ src/libqhull_r/qh-qhull_r.htm
+ src/libqhull_r/qh-set_r.htm
+ src/libqhull_r/qh-stat_r.htm
+ src/libqhull_r/qh-user_r.htm
+)
+
+set(
+ testqsetr_HEADERS
+ src/libqhull_r/mem_r.h
+ src/libqhull_r/qset_r.h
+)
+set(
+ testqsetr_SOURCES
+ src/libqhull_r/qset_r.c
+ src/libqhull_r/mem_r.c
+ src/testqset_r/testqset_r.c
+ ${testqsetr_HEADERS}
+)
+
+# C++ interface to reentrant Qhull
+
set(
libqhullcpp_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/libqhullcpp/UsingLibQhull.h
src/qhulltest/RoadTest.h
)
set(
libqhullcpp_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
- src/libqhullcpp/UsingLibQhull.cpp
${libqhullcpp_HEADERS}
)
+# Documentation files (index.htm refers to html/...)
+
set(
doc_FILES
README.txt
REGISTER.txt
Announce.txt
COPYING.txt
index.htm
)
-include_directories(${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/libqhull)
+include_directories(${CMAKE_SOURCE_DIR}/src)
if(CMAKE_BUILD_TYPE MATCHES "[dD]ebug")
set(qhull_CPP qhullcpp_d)
- set(qhull_SHARED qhull_d)
+ set(qhull_SHARED qhull_d)
set(qhull_SHAREDP qhull_pd)
+ set(qhull_SHAREDR qhull_rd)
set(qhull_STATIC qhullstatic_d)
- set(qhull_STATICP qhullstatic_pd)
+ set(qhull_STATICR qhullstatic_rd)
else()
set(qhull_CPP qhullcpp)
- set(qhull_SHARED libqhull) # Avoid name conflict with qhull executable
+ set(qhull_SHARED libqhull) # Temporarily avoid name conflict with qhull executable
set(qhull_SHAREDP qhull_p)
+ set(qhull_SHAREDR qhull_r)
set(qhull_STATIC qhullstatic)
- set(qhull_STATICP qhullstatic_p)
+ set(qhull_STATICR qhullstatic_r)
endif()
set(
qhull_TARGETS_INSTALL
- ${qhull_CPP} ${qhull_STATIC} ${qhull_STATICP} ${qhull_SHARED} ${qhull_SHAREDP}
+ ${qhull_CPP} ${qhull_STATIC} ${qhull_STATICR} ${qhull_SHAREDR}
qhull rbox qconvex qdelaunay qvoronoi qhalf
+ ${qhull_SHARED} ${qhull_SHAREDP} # Deprecated, remains in use as libqhull6
)
set(
- qhull_TARGETS_TEST
- user_eg user_eg2 user_eg3 testqset
-)
-set(
- qhull_TARGETS
- ${qhull_TARGETS_INSTALL} ${qhull_TARGETS_TEST}
+ qhull_TARGETS_TEST # Unused
+ user_eg user_eg2 user_eg3 testqset testqset_r
)
+# ---------------------------------------
+# Define shared library for reentrant qhull (installed)
+# ---------------------------------------
+
+add_library(${qhull_SHAREDR} SHARED
+ ${libqhullr_SOURCES}
+ src/libqhull_r/qhull_r-exports.def)
+set_target_properties(${qhull_SHAREDR} PROPERTIES
+ SOVERSION ${qhull_SOVERSION}
+ VERSION ${qhull_VERSION})
+
+if(UNIX)
+ target_link_libraries(${qhull_SHAREDR} m)
+ if(APPLE)
+ set_target_properties(${qhull_SHAREDR} PROPERTIES
+ INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
+ else()
+ set_target_properties(${qhull_SHAREDR} PROPERTIES
+ INSTALL_RPATH "${LIB_INSTALL_DIR}"
+ INSTALL_RPATH_USE_LINK_PATH TRUE
+ BUILD_WITH_INSTALL_RPATH FALSE)
+ endif()
+endif(UNIX)
# ---------------------------------------
-# Define shared library qhull without qh_QHpointer
+# Define shared library for non-reentrant qhull without qh_QHpointer
# ---------------------------------------
add_library(${qhull_SHARED} SHARED
${libqhull_SOURCES}
src/libqhull/qhull-exports.def)
if(qhull_SHARED MATCHES "libqhull")
+ set(qhull_OUTPUT_NAME qhull)
set_target_properties(${qhull_SHARED} PROPERTIES
- OUTPUT_NAME "qhull")
+ OUTPUT_NAME "${qhull_OUTPUT_NAME}" )
endif()
set_target_properties(${qhull_SHARED} PROPERTIES
- SOVERSION ${qhull_SOVERSION})
+ SOVERSION ${qhull_SOVERSION}
+ VERSION ${qhull_VERSION})
if(UNIX)
target_link_libraries(${qhull_SHARED} m)
if(APPLE)
set_target_properties(${qhull_SHARED} PROPERTIES
INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
else()
set_target_properties(${qhull_SHARED} PROPERTIES
INSTALL_RPATH "${LIB_INSTALL_DIR}"
INSTALL_RPATH_USE_LINK_PATH TRUE
BUILD_WITH_INSTALL_RPATH FALSE)
endif()
endif(UNIX)
# ---------------------------------------
-# Define shared library qhull with qh_QHpointer
+# Define old shared library qhull with qh_QHpointer
# ---------------------------------------
add_library(${qhull_SHAREDP} SHARED
${libqhull_SOURCES}
- src/libqhullp/qhull_p-exports.def)
+ src/libqhull/qhull_p-exports.def)
set_target_properties(${qhull_SHAREDP} PROPERTIES
COMPILE_DEFINITIONS "qh_QHpointer"
- SOVERSION ${qhull_SOVERSION})
+ SOVERSION ${qhull_SOVERSION}
+ VERSION ${qhull_VERSION})
if(UNIX)
target_link_libraries(${qhull_SHAREDP} m)
if(APPLE)
set_target_properties(${qhull_SHAREDP} PROPERTIES
INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
else()
set_target_properties(${qhull_SHAREDP} PROPERTIES
INSTALL_RPATH "${LIB_INSTALL_DIR}"
INSTALL_RPATH_USE_LINK_PATH TRUE
BUILD_WITH_INSTALL_RPATH FALSE)
endif()
endif(UNIX)
# ---------------------------------------
-# Define static libraries qhullstatic and qhullstatic_p (qh_QHpointer)
+# Define static libraries qhullstatic (non-reentrant) and qhullstatic_r (reentrant)
# ---------------------------------------
add_library(${qhull_STATIC} STATIC ${libqhull_SOURCES})
set_target_properties(${qhull_STATIC} PROPERTIES
VERSION ${qhull_VERSION})
-add_library(${qhull_STATICP} STATIC ${libqhull_SOURCES})
-set_target_properties(${qhull_STATICP} PROPERTIES
- COMPILE_DEFINITIONS "qh_QHpointer"
+add_library(${qhull_STATICR} STATIC ${libqhullr_SOURCES})
+set_target_properties(${qhull_STATICR} PROPERTIES
VERSION ${qhull_VERSION})
if(UNIX)
target_link_libraries(${qhull_STATIC} m)
- target_link_libraries(${qhull_STATICP} m)
+ target_link_libraries(${qhull_STATICR} m)
endif(UNIX)
# ---------------------------------------
-# Define C++ static library qhullcpp (qh_QHpointer)
+# Define C++ static library qhullcpp
# ---------------------------------------
add_library(${qhull_CPP} STATIC ${libqhullcpp_SOURCES})
set_target_properties(${qhull_CPP} PROPERTIES
- COMPILE_DEFINITIONS "qh_QHpointer"
VERSION ${qhull_VERSION})
# ---------------------------------------
# Define qhull executables linked to qhullstatic library
+# qhull is linked to reentrant qhull (more flexible)
+# the others are linked to non-reentrant qhull (somewhat faster)
# ---------------------------------------
-set(qhull_SOURCES src/qhull/unix.c)
+set(qhull_SOURCES src/qhull/unix_r.c)
set(rbox_SOURCES src/rbox/rbox.c)
set(qconvex_SOURCES src/qconvex/qconvex.c)
set(qdelaunay_SOURCES src/qdelaunay/qdelaun.c)
set(qvoronoi_SOURCES src/qvoronoi/qvoronoi.c)
set(qhalf_SOURCES src/qhalf/qhalf.c)
-set(user_eg2_SOURCES src/user_eg2/user_eg2.c)
-if(MSVC)
- set(user_eg_DEFINES qh_QHpointer qh_QHpointer_dllimport)
- set(user_eg2_DEFINES qh_dllimport)
-else()
- set(user_eg_DEFINES qh_QHpointer)
- set(user_eg2_DEFINES )
-endif()
add_executable(qhull ${qhull_SOURCES})
-target_link_libraries(qhull ${qhull_STATIC})
+target_link_libraries(qhull ${qhull_STATICR})
add_executable(rbox ${rbox_SOURCES})
target_link_libraries(rbox ${qhull_STATIC})
add_executable(qconvex ${qconvex_SOURCES})
target_link_libraries(qconvex ${qhull_STATIC})
add_executable(qdelaunay ${qdelaunay_SOURCES})
target_link_libraries(qdelaunay ${qhull_STATIC})
add_executable(qvoronoi ${qvoronoi_SOURCES})
target_link_libraries(qvoronoi ${qhull_STATIC})
add_executable(qhalf ${qhalf_SOURCES})
target_link_libraries(qhalf ${qhull_STATIC})
+# ---------------------------------------
+# Define options for linking to qhull_SHAREDR or qhull_SHARED
+# ---------------------------------------
+if(MSVC)
+ set(user_eg_DEFINES qh_dllimport)
+ set(user_eg2_DEFINES qh_dllimport)
+ set(user_eg3_DEFINES qh_dllimport)
+else()
+ set(user_eg_DEFINES )
+ set(user_eg2_DEFINES )
+ set(user_eg3_DEFINES )
+endif()
+
# ---------------------------------------
# Define testqset linked to qset.o and mem.o
+# Define testqset_r linked to qset_r.o and mem_r.o
# ---------------------------------------
add_executable(testqset ${testqset_SOURCES})
+add_executable(testqset_r ${testqsetr_SOURCES})
# ---------------------------------------
-# Define user_eg linked to qhull shared library with qh_QHpointer
+# Define user_eg linked to reentrant qhull shared library
# ---------------------------------------
-set(user_eg_SOURCES src/user_eg/user_eg.c)
+set(user_eg_SOURCES src/user_eg/user_eg_r.c)
add_executable(user_eg ${user_eg_SOURCES})
-# user_eg may be linked to qhull_STATIC if user_eg_DEFINES is removed
-target_link_libraries(user_eg ${qhull_SHAREDP})
+# user_eg may be linked to qhull_STATICR if user_eg_DEFINES is removed
+target_link_libraries(user_eg ${qhull_SHAREDR})
set_target_properties(user_eg PROPERTIES
COMPILE_DEFINITIONS "${user_eg_DEFINES}")
# ---------------------------------------
-# Define user_eg2 linked to qhull shared library (e.g., Debian)
+# Define user_eg2 linked to reentrant qhull static library
# ---------------------------------------
+set(user_eg2_SOURCES src/user_eg2/user_eg2_r.c)
+
add_executable(user_eg2 ${user_eg2_SOURCES})
-target_link_libraries(user_eg2 ${qhull_SHARED})
-set_target_properties(user_eg2 PROPERTIES
- COMPILE_DEFINITIONS "${user_eg2_DEFINES}")
+# user_eg2 may be linked to qhull_SHAREDR if user_eg2_DEFINES is added
+target_link_libraries(user_eg2 ${qhull_STATICR})
# ---------------------------------------
-# Define user_eg3 linked to qhullstatic_p and qhullcpp static library
+# Define user_eg3 linked to qhullstatic_r and qhullcpp static library
+#
+# user_eg3 and qhullcpp must be compiled with the same compiler for setjmp/longjmp
# ---------------------------------------
-# libqhullcpp must be before src/libqhull. The later is not needed.
-# Otherwise get error -- user_eg3.cpp:72: error: aggregate 'orgQhull::Qhull qhull' has incomplete type and cannot be defined
-include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src/libqhullcpp)
-
-set(user_eg3_SOURCES src/user_eg3/user_eg3.cpp)
+set(user_eg3_SOURCES src/user_eg3/user_eg3_r.cpp)
add_executable(user_eg3 ${user_eg3_SOURCES})
-# qhull_STATICP must be last, otherwise qh_fprintf,etc. are not loaded from qhull_CPP
-target_link_libraries(user_eg3 ${qhull_CPP} ${qhull_STATICP})
-set_target_properties(user_eg3 PROPERTIES
- COMPILE_DEFINITIONS "qh_QHpointer")
+# qhull_STATICR must be last, otherwise qh_fprintf,etc. are not loaded from qhull_CPP
+# user_eg3 may be linked to qhull_SHAREDR if user_eg3_DEFINES is added
+target_link_libraries(user_eg3 ${qhull_CPP} ${qhull_STATICR})
+
+# ---------------------------------------
+# Define test
+# ---------------------------------------
+
+enable_testing()
+add_test(NAME testqset
+ COMMAND ./testqset 10000)
+add_test(NAME testqset_r
+ COMMAND ./testqset_r 10000)
+add_test(NAME smoketest
+ COMMAND sh -c "./rbox D4 | ./qhull Tv")
+add_test(NAME rbox-10-qhull
+ COMMAND sh -c "./rbox 10 | ./qhull Tv")
+add_test(NAME rbox-10-qconvex
+ COMMAND sh -c "./rbox 10 | ./qconvex Tv")
+add_test(NAME rbox-10-qdelaunay
+ COMMAND sh -c "./rbox 10 | ./qdelaunay Tv")
+add_test(NAME rbox-10-qhalf
+ COMMAND sh -c "./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv")
+add_test(NAME rbox-10-qvoronoi
+ COMMAND sh -c "./rbox 10 | ./qvoronoi Tv")
+add_test(NAME user_eg
+ COMMAND sh -c "./user_eg")
+add_test(NAME user_eg2
+ COMMAND sh -c "./user_eg2")
+add_test(NAME user_eg3
+ COMMAND sh -c "./user_eg3 rbox '10 D2' '2 D2' qhull 's p' facets")
# ---------------------------------------
# Define install
# ---------------------------------------
install(TARGETS ${qhull_TARGETS_INSTALL}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
install(FILES ${libqhull_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull)
install(FILES ${libqhull_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull)
+install(FILES ${libqhullr_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull_r)
+install(FILES ${libqhullr_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull_r)
install(FILES ${libqhullcpp_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhullcpp)
install(FILES html/qhull.man DESTINATION ${MAN_INSTALL_DIR} RENAME qhull.1)
install(FILES html/rbox.man DESTINATION ${MAN_INSTALL_DIR} RENAME rbox.1)
install(FILES ${doc_FILES} DESTINATION ${DOC_INSTALL_DIR})
install(DIRECTORY html/ DESTINATION ${DOC_INSTALL_DIR})
diff --git a/File_id.diz b/File_id.diz
index d5e85d1..10cdb9c 100644
--- a/File_id.diz
+++ b/File_id.diz
@@ -1,12 +1,12 @@
-Qhull 2012.1 - Qhull computes convex hulls,
+Qhull 2015.0.2 - Qhull computes convex hulls,
Delaunay triangulations, halfspace inter-
sections about a point, Voronoi diagrams,
furthest-site Delaunay triangulations, and
furthest-site Voronoi diagrams. Qhull
works with 2-d, 3-d, 4-d, 5-d, and higher
dimensions. It computes volumes, surface
areas, and approximations. It runs in a
command window under Windows 95/NT/XP/7.
www.qhull.org, freeware.
diff --git a/Makefile b/Makefile
index c15bd5b..48e9f7a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,567 +1,672 @@
-# Unix Makefile for qhull and rbox (default gcc/g++)
+# Unix Makefile for reentrant libqhull, qhull, and rbox (default gcc/g++)
#
# see README.txt and 'make help'
-# For qhulltest, use Qt project file at src/qhull-all.pro
-# For static builds, an alternative is src/libqhull/Makefile
+# For qhulltest of the C++ interface, use Qt project file at src/qhull-all.pro
+# For static builds, a simple alternative is src/libqhull_r/Makefile
#
# Results
-# qhull Computes convex hull and related structures (libqhullstatic)
+# qhull Computes convex hull and related structures using reentrant libqhullstatic_r
+# rbox Generates point sets for qhull
# qconvex, qdelaunay, qhalf, qvoronoi
# Specializations of qhull for each geometric structure
-# libqhull.so Shared library with a static qh_qh struct
-# libqhull_p.so ... with a malloc'd qh_qh struct with -Dqh_QHpointer
-# make SO=dll ... on Windows, use SO=dll. It compiles dlls
-# libqhullstatic.a Static library with a static qh_qh struct
+# Built with non-reentrant libqhullstatic (somewhat faster)
+# libqhull_r.so Shared library with reentrant code
+# libqhullstatic.a Non-reentrant static library with static qh_qh struct
# ... called 'static' to avoid naming conflicts
-# libqhullstatic_p.a with a malloc'd qh_qh struct with -Dqh_QHpointer
-# libqhullcpp.a Static library using a malloc'd qh_qh struct
-# user_eg An example of using shared library qhull_p
-# ... compiled with -Dqh_QHpointer
-# user_eg2 An example of using shared library qhull
+# libqhullstatic_r.a Reentrant, static library
+# libqhullcpp.a C++ static library (using libqhullstatic_r.a)
+# user_eg An example of using reentrant, shared library qhull_r
+# user_eg2 An example of using reentrant, static library libqhullstatic_r
# user_eg3 An example of the C++ interface to qhull
-# ... using libqhullcpp, libqhullstatic_p, -Dqh_QHpointer
-# testqset Standalone test program for qset.c with mem.c
+# ... using libqhullcpp and reentrant libqhullstatic_r
+# testqset Standalone test program for non-reentrant qset.c with mem.c
+# testqset_r Standalone test program for reentrant qset_r.c with mem_r.c
#
# Make targets
-# make Produce all of the results
+# make Produce all of the results using gcc or another compiler
+# make SO=dll on Windows, use SO=dll. It compiles dlls
+# make help
# make qhullx Produce qhull, qconvex etc. without using library
# make qtest Quick test of rbox and qhull (bin/rbox D4 | bin/qhull)
-# make qtestall Quick test of all programs except qhulltest
-# make test Test of rbox and qhull
+# make test Quick test of all programs except qhulltest
+# make testall Test of rbox and qhull for manual review
# make bin/qvoronoi Produce bin/qvoronoi (etc.)
# make doc Print documentation
# 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 clean Remove object files
-# make cleanall Remove generated files
+# make cleanall Remove generated files, build/*.dlr/, buildqt/, and buildvc/
#
-# DESTDIR destination directory. Other directories are relative
+# DESTDIR destination directory for 'make install'.
# BINDIR directory where to copy executables
# 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
# CXX ANSI C++ compiler
# CXX_OPTS1 options used to compile .cpp files
# CXX_OPTS2 options used to link .o files
# CC_WARNINGS warnings for .c programs
# CXX_WARNINGS warnings for .cpp programs
#
-# LIBQHULLS_OBJS .o files for linking
-# LIBQHULL_HDRS .h files for printing
+# LIBQHULLS_RBOX_OBJS .o files for linking
+# LIBQHULLR_HDRS non-reentrant .h files
+# LIBQHULLR_HDRS reentrant .h files
# CFILES .c files for printing
# CXXFILES .cpp files for printing
# TESTFILES .cpp test files for printing
# DOCFILES documentation files
# FILES miscellaneous files for printing
# HTMFILES documentation source files
# TFILES .txt versions of html files
# FILES all other files
-# LIBQHULLS_OBJS specifies the object files of libqhullstatic.a
+# LIBQHULLS_RBOX_OBJS specifies the object files of libqhullstatic.a
#
# Do not replace tabs with spaces. Needed by 'make' for build rules
-
+#
# You may build the qhull programs without using a library
-# make qhullx
+# make qhullx
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, -O2 for optimization, -g for debugging
+#for Gnu's gcc compiler, -O3 for optimization, -g for debugging
+# -fPIC needed for gcc x86_64-linux-gnu. Not needed for mingw
CC = gcc
-CC_OPTS1 = -O2 -fPIC -ansi -Isrc/libqhull $(CC_WARNINGS)
+CC_OPTS1 = -O3 -ansi -Isrc -fPIC $(CC_WARNINGS)
CXX = g++
-# libqhullcpp must be before libqhull
-CXX_OPTS1 = -O2 -Dqh_QHpointer -Isrc/ -Isrc/libqhullcpp -Isrc/libqhull $(CXX_WARNINGS)
+# libqhullcpp must be before libqhull_r
+CXX_OPTS1 = -O3 -Isrc/ $(CXX_WARNINGS)
# for shared library link
CC_OPTS3 =
# Define qhull_VERSION in CMakeLists.txt, Makefile, and qhull-warn.pri
# Truncated version in qhull-exports.def, qhull_p-exports.def,
# qhull.so -- static qh_qhT global data structure (qh_QHpointer=0)
# qhull_p.so -- allocated qh_qhT global data structure (qh_QHpointer=1). Required for libqhullcpp
# qhull_m.so -- future version of Qhull with qh_qhT passed as an argument.
-qhull_SOVERSION=6
-SO = so.6.3.1
+qhull_SOVERSION=7
+SO = so.7.0.1
# On MinGW,
# make SO=dll
# Copy lib/libqhull6_p.dll and lib/libqhull.dll to bin/
# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
#CC = cc
#CC_OPTS1 = -Xc -v -fast
# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
#CC = cc
#CC_OPTS1 = -ansi -O2
# for Next cc compiler with fat executable
#CC = cc
#CC_OPTS1 = -ansi -O2 -arch m68k -arch i386 -arch hppa
# For loader, ld,
CC_OPTS2 = $(CC_OPTS1)
CXX_OPTS2 = $(CXX_OPTS1)
# [gcc 4.4] Compiles without error (-Werror)
CC_WARNINGS = -Wall -Wcast-qual -Wextra -Wwrite-strings -Wshadow
CXX_WARNINGS = -Wall -Wcast-qual -Wextra -Wwrite-strings -Wno-sign-conversion -Wshadow -Wconversion
+# FIXUP -Wunused-but-set-variable
# Compiles OK with all gcc warnings except for -Wno-sign-conversion and -Wconversion
+# --help=warnings
# Compiles OK with all g++ warnings except Qt source errors on -Wshadow and -Wconversion
# -Waddress -Warray-bounds -Wchar-subscripts -Wclobbered -Wcomment -Wunused-variable
# -Wempty-body -Wformat -Wignored-qualifiers -Wimplicit-function-declaration -Wimplicit-int
# -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-parameter-type -Wnonnull
# -Wold-style-declaration -Woverride-init -Wparentheses -Wpointer-sign -Wreturn-type
# -Wsequence-point -Wsign-compare -Wsign-compare -Wstrict-aliasing -Wstrict-overflow=1
# -Wswitch -Wtrigraphs -Wtype-limits -Wuninitialized -Wuninitialized -Wvolatile-register-var
# -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value
# Default targets for make
-all: bin-lib bin/rbox bin/qconvex bin/qdelaunay bin/qhalf bin/qvoronoi \
- bin/qhull bin/testqset qtest bin/user_eg2 bin/user_eg3 bin/user_eg qconvex-prompt
+all: bin-lib bin/rbox bin/qconvex bin/qdelaunay bin/qhalf bin/qvoronoi bin/qhull bin/testqset \
+ bin/testqset_r qtest bin/user_eg2 bin/user_eg3 bin/user_eg qconvex-prompt
help:
- head -n 50 Makefile
+ head -n 78 Makefile
bin-lib:
mkdir -p bin lib
# Remove intermediate files for all builds
clean:
rm -f src/*/*.o src/qhulltest/RoadTest.h.cpp build/*/*/*.o build/*/*.o
rm -f src/*/*.obj build/*/*/*.obj build/*/*/*/*/*.obj build/*/*.obj
rm -f bin/*.idb lib/*.idb build-cmake/*/*.idb
rm -f build/*/*/*.a build/*/*/*.rsp build/moc/*.moc
rm -f build-cmake/*/*.obj build-cmake/*/*/*.obj build-cmake/*/*.ilk
# Remove intermediate files and targets for all builds
+# DevStudio prevents build/qhull.ncb deletes
cleanall: clean
+ rm -rf build/*.dir/
+ -rm -rf build/qhull.ncb
+ rm -rf buildvc/
+ rm -rf buildqt/
+ rm -rf build-qhull-all*/
+ rm -f eg/eg.*
rm -f bin/qconvex bin/qdelaunay bin/qhalf bin/qvoronoi bin/qhull
- rm -f core bin/core bin/user_eg bin/user_eg2 bin/user_eg3
+ rm -f bin/rbox core bin/core bin/user_eg bin/user_eg2 bin/user_eg3
rm -f lib/libqhull* lib/qhull*.lib lib/qhull*.exp lib/qhull*.dll
rm -f bin/libqhull* bin/qhull*.dll bin/*.exe bin/*.pdb lib/*.pdb
rm -f build/*.dll build/*.exe build/*.a build/*.exp
- rm -f build/*.lib build/*.pdb build/*.idb
+ rm -f build/*.lib build/*.pdb build/*.idb build/qhull-no-qt.sln
rm -f build-cmake/*/*.dll build-cmake/*/*.exe build-cmake/*/*.exp
rm -f build-cmake/*/*.lib build-cmake/*/*.pdb
+ rm -f src/libqhull/qconvex.c src/libqhull/qdelaun.c src/libqhull/qhalf.c
+ rm -f src/libqhull/qvoronoi.c src/libqhull/rbox.c src/libqhull/testqset.c
+ rm -f src/libqhull/unix.c src/libqhull/user_eg.c src/libqhull/user_eg2.c
+ rm -f src/libqhull/*.exe src/libqhull/libqhullstatic* src/libqhull/core
+ rm -f src/libqhull/qconvex src/libqhull/qdelaunay src/libqhull/qhalf src/libqhull/qvoronoi src/libqhull/qhull
+ rm -f src/libqhull/rbox src/libqhull/core src/libqhull/user_eg src/libqhull/user_eg2 src/libqhull/user_eg3
+ rm -f src/libqhull_r/unix_r.c src/libqhull_r/user_eg_r.c src/libqhull_r/user_eg2_r.c
+ rm -f src/libqhull_r/qconvex_r.c src/libqhull_r/qdelaun_r.c src/libqhull_r/qhalf_r.c
+ rm -f src/libqhull_r/qvoronoi_r.c src/libqhull_r/rbox_r.c src/libqhull_r/testqset_r.c
+ rm -f src/libqhull_r/unix_r.c src/libqhull_r/user_eg_r.c src/libqhull_r/user_eg2_r.c
+ rm -f src/libqhull_r/*.exe src/libqhull_r/libqhullstatic*
+ rm -f src/libqhull_r/qconvex src/libqhull_r/qdelaunay src/libqhull_r/qhalf src/libqhull_r/qvoronoi src/libqhull_r/qhull
+ rm -f src/libqhull_r/rbox src/libqhull_r/core src/libqhull_r/user_eg src/libqhull_r/user_eg2 src/libqhull_r/user_eg3
doc:
$(PRINTMAN) $(TXTFILES) $(DOCFILES)
install:
mkdir -p $(BINDIR)
mkdir -p $(DOCDIR)
mkdir -p $(INCDIR)/libqhull
+ mkdir -p $(INCDIR)/libqhull_r
mkdir -p $(INCDIR)/libqhullcpp
mkdir -p $(LIBDIR)
mkdir -p $(MANDIR)
cp bin/qconvex $(BINDIR)
cp bin/qdelaunay $(BINDIR)
cp bin/qhalf $(BINDIR)
cp bin/qhull $(BINDIR)
cp bin/qvoronoi $(BINDIR)
cp bin/rbox $(BINDIR)
cp html/qhull.man $(MANDIR)/qhull.1
cp html/rbox.man $(MANDIR)/rbox.1
cp html/* $(DOCDIR)
cp -P lib/* $(LIBDIR)
- cp src/libqhull/*.h src/libqhull/*.htm $(INCDIR)/libqhull
+ cp src/libqhull/DEPRECATED.txt src/libqhull/*.h src/libqhull/*.htm $(INCDIR)/libqhull
+ cp src/libqhull_r/*.h src/libqhull_r/*.htm $(INCDIR)/libqhull_r
cp src/libqhullcpp/*.h $(INCDIR)/libqhullcpp
cp src/qhulltest/*.h $(INCDIR)/libqhullcpp
new: cleanall all
printall: doc printh printc printf
printh:
$(PRINTC) $(LIBQHULL_HDRS)
+ $(PRINTC) $(LIBQHULLR_HDRS)
$(PRINTC) $(LIBQHULLCPP_HDRS)
printc:
$(PRINTC) $(CFILES)
$(PRINTC) $(CXXFILES)
$(PRINTC) $(TESTFILES)
printf:
$(PRINTC) $(FILES)
qtest:
- @echo ==============================
- @echo == Test qset.c with mem.c ====
- @echo ==============================
+ @echo ============================================
+ @echo == make qtest ==============================
+ @echo ============================================
+ @echo -n "== "
+ @date
+ @echo
+ @echo ============================================
+ @echo == Test non-reentrant qset.c with mem.c ====
+ @echo ============================================
-bin/testqset 10000
+ @echo
+ @echo ============================================
+ @echo == Test reentrant qset_r.c with mem_r.c ====
+ @echo ============================================
+ -bin/testqset_r 10000
+ @echo
+ @echo ============================================
+ @echo == Run the qhull smoketest ====
+ @echo ============================================
+ -bin/rbox D4 | bin/qhull Tv
+
+test: qtest
+ @echo ============================================
+ @echo == make test ===============================
+ @echo ============================================
+ @echo
@echo ==============================
- @echo == Run the qhull smoketest ===
+ @echo ========= rbox/qhull =======
@echo ==============================
-bin/rbox D4 | bin/qhull Tv
-
-qtestall: qtest
+ @echo
@echo ==============================
@echo ========= qconvex ============
@echo ==============================
-bin/rbox 10 | bin/qconvex Tv
+ @echo
@echo ==============================
@echo ========= qdelaunay ==========
@echo ==============================
-bin/rbox 10 | bin/qdelaunay Tv
+ @echo
@echo ==============================
@echo ========= qhalf ==============
@echo ==============================
-bin/rbox 10 | bin/qconvex FQ FV n Tv | bin/qhalf Tv
+ @echo
@echo ==============================
@echo ========= qvoronoi ===========
@echo ==============================
-bin/rbox 10 | bin/qvoronoi Tv
+ @echo
@echo ==============================
@echo ========= user_eg ============
@echo ==============================
-bin/user_eg
+ @echo
@echo ==============================
@echo ========= user_eg2 ===========
@echo ==============================
-bin/user_eg2
+ @echo
@echo ==============================
@echo ========= user_eg3 ===========
@echo ==============================
-bin/user_eg3 rbox "10 D2" "2 D2" qhull "s p" facets
-test:
+# make testall >q_test.txt 2>&1
+testall: test
+ @echo ============================================
+ @echo == make testall ============================
+ @echo ============================================
+ @echo -n "== "
+ @date
+ @echo
-eg/q_eg
-eg/q_egtest
-eg/q_test
qconvex-prompt:
- -bin/qconvex
- @echo '== For libqhull.so and libqhull_p.so'
- @echo ' export LD_LIBRARY_PATH=$$PWD/lib:$$LD_LIBRARY_PATH'
+ bin/qconvex
+ @echo
+ @echo ============================================
+ @echo == Run the qconvex smoketest
+ @echo ============================================
+ bin/rbox D4 | bin/qconvex Tv
@echo
- @echo '== For libqhull.dll and libqhull_p.dll'
- @echo ' cp lib/libqhull*.dll bin'
+ @echo ============================================
+ @echo == To enable user_eg and user_eg2
+ @echo ==
+ @echo == Windows -- make SO=dll
+ @echo '== cp -p lib/libqhull*.dll bin'
+ @echo ==
+ @echo == Unix/Macintosh -- make
+ @echo '== export LD_LIBRARY_PATH=$$PWD/lib:$$LD_LIBRARY_PATH'
+ @echo ============================================
@echo
- @echo '== The previous steps are required for user_eg and user_eg2'
+ @echo ============================================
+ @echo == To smoketest qhull programs
+ @echo '== make test'
+ @echo ============================================
@echo
- @echo '== To smoketest each program'
- @echo ' make qtestall'
+ @echo ============================================
+ @echo == To run qhull tests for manual review with eg/q_test-ok.txt
+ @echo '== make testall >q_test.txt 2>&1'
+ @echo ============================================
+ @echo
+ @echo ============================================
+ @echo == For all make targets
+ @echo '== make help'
+ @echo ============================================
@echo
+# libqhull is source files for non-reentrant Qhull
+# libqhull_r is source files and a shared library for reentrant Qhull
L= src/libqhull
+LR= src/libqhull_r
+
+# libqhullstatic is a static library for non-reentrant Qhull
+# libqhullstatic_r is a static library for reentrant Qhull
LS= src/libqhullstatic
-LSP= src/libqhullstaticp
+LSR= src/libqhullstatic_r
+
+# libqhullcpp is a shared library for C++ files and libqhull_r
+# qhulltest is a Qt test of libqhullcpp
LCPP= src/libqhullcpp
TCPP= src/qhulltest
LIBQHULL_HDRS = $(L)/user.h $(L)/libqhull.h $(L)/qhull_a.h $(L)/geom.h \
$(L)/io.h $(L)/mem.h $(L)/merge.h $(L)/poly.h $(L)/random.h \
$(L)/qset.h $(L)/stat.h
-# LIBQHULLS_OBJS_1 and LIBQHULLSP_OBJS ordered by frequency of execution with
+LIBQHULLR_HDRS = $(LR)/user_r.h $(LR)/libqhull_r.h $(LR)/qhull_ra.h $(LR)/geom_r.h \
+ $(LR)/io_r.h $(LR)/mem_r.h $(LR)/merge_r.h $(LR)/poly_r.h $(LR)/random_r.h \
+ $(LR)/qset_r.h $(LR)/stat_r.h
+
+# LIBQHULLS_OBJS and LIBQHULLSR_OBJS ordered by frequency of execution with
# small files at end. Better locality.
-LIBQHULLS_OBJS_1= $(LS)/global.o $(LS)/stat.o $(LS)/geom2.o $(LS)/poly2.o \
+LIBQHULLS_OBJS= $(LS)/global.o $(LS)/stat.o $(LS)/geom2.o $(LS)/poly2.o \
$(LS)/merge.o $(LS)/libqhull.o $(LS)/geom.o $(LS)/poly.o \
$(LS)/qset.o $(LS)/mem.o $(LS)/random.o
-LIBQHULLS_OBJS_2 = $(LIBQHULLS_OBJS_1) $(LS)/usermem.o $(LS)/userprintf.o \
+LIBQHULLS_USER_OBJS = $(LIBQHULLS_OBJS) $(LS)/usermem.o $(LS)/userprintf.o \
$(LS)/io.o $(LS)/user.o
-LIBQHULLS_OBJS = $(LIBQHULLS_OBJS_2) $(LS)/rboxlib.o $(LS)/userprintf_rbox.o
+LIBQHULLS_RBOX_OBJS = $(LIBQHULLS_USER_OBJS) $(LS)/rboxlib.o $(LS)/userprintf_rbox.o
+
+LIBQHULLSR_OBJS = $(LSR)/global_r.o $(LSR)/stat_r.o $(LSR)/geom2_r.o $(LSR)/poly2_r.o \
+ $(LSR)/merge_r.o $(LSR)/libqhull_r.o $(LSR)/geom_r.o $(LSR)/poly_r.o \
+ $(LSR)/qset_r.o $(LSR)/mem_r.o $(LSR)/random_r.o
+
+LIBQHULLSR_USER_OBJS = $(LIBQHULLSR_OBJS) $(LSR)/usermem_r.o $(LSR)/userprintf_r.o \
+ $(LSR)/io_r.o $(LSR)/user_r.o
-LIBQHULLSP_OBJS = $(LSP)/global.o $(LSP)/stat.o \
- $(LSP)/geom2.o $(LSP)/poly2.o $(LSP)/merge.o \
- $(LSP)/libqhull.o $(LSP)/geom.o $(LSP)/poly.o $(LSP)/qset.o \
- $(LSP)/mem.o $(LSP)/random.o $(LSP)/usermem.o $(LSP)/userprintf.o \
- $(LSP)/io.o $(LSP)/user.o $(LSP)/rboxlib.o $(LSP)/userprintf_rbox.o
+LIBQHULLSR_RBOX_OBJS = $(LIBQHULLSR_USER_OBJS) $(LSR)/rboxlib_r.o $(LSR)/userprintf_rbox_r.o
LIBQHULLCPP_HDRS = $(LCPP)/RoadError.h $(LCPP)/RoadLogEvent.h $(LCPP)/Coordinates.h \
$(LCPP)/QhullHyperplane.h $(LCPP)/functionObjects.h $(LCPP)/PointCoordinates.h \
$(LCPP)/Qhull.h $(LCPP)/QhullError.h $(LCPP)/QhullFacet.h \
$(LCPP)/QhullFacetList.h $(LCPP)/QhullFacetSet.h $(LCPP)/QhullIterator.h \
$(LCPP)/QhullLinkedList.h $(LCPP)/QhullPoint.h $(LCPP)/QhullPoints.h \
$(LCPP)/QhullPointSet.h $(LCPP)/QhullQh.h $(LCPP)/QhullRidge.h \
$(LCPP)/QhullSet.h $(LCPP)/QhullSets.h $(LCPP)/QhullStat.h \
- $(LCPP)/QhullVertex.h $(LCPP)/RboxPoints.h $(LCPP)/UsingLibQhull.h
+ $(LCPP)/QhullVertex.h $(LCPP)/RboxPoints.h
LIBQHULLCPP_OBJS = $(LCPP)/RoadError.o $(LCPP)/RoadLogEvent.o $(LCPP)/Coordinates.o \
$(LCPP)/PointCoordinates.o $(LCPP)/Qhull.o $(LCPP)/QhullFacet.o \
$(LCPP)/QhullFacetList.o $(LCPP)/QhullFacetSet.o \
$(LCPP)/QhullHyperplane.o $(LCPP)/QhullPoint.o \
$(LCPP)/QhullPoints.o $(LCPP)/QhullPointSet.o $(LCPP)/QhullQh.o \
$(LCPP)/QhullRidge.o $(LCPP)/QhullSet.o $(LCPP)/QhullStat.o \
$(LCPP)/QhullVertex.o $(LCPP)/QhullVertexSet.o $(LCPP)/RboxPoints.o \
- $(LCPP)/UsingLibQhull.o src/user_eg3/user_eg3.o
+ src/user_eg3/user_eg3_r.o
-# CFILES ordered alphabetically after libqhull.c
+# CFILES for non-reentrant Qhull, ordered alphabetically after libqhull.c
CFILES= src/qhull/unix.c $(L)/libqhull.c $(L)/geom.c $(L)/geom2.c $(L)/global.c $(L)/io.c \
$(L)/mem.c $(L)/merge.c $(L)/poly.c $(L)/poly2.c $(L)/random.c $(L)/rboxlib.c \
$(L)/qset.c $(L)/stat.c $(L)/user.c $(L)/usermem.c $(L)/userprintf.c $(L)/userprintf_rbox.c \
src/qconvex/qconvex.c src/qdelaunay/qdelaun.c src/qhalf/qhalf.c src/qvoronoi/qvoronoi.c
-CXXFILES= $(LCPP)/RoadError.cpp $(LCPP)/RoadLogEvent.cpp $(LCPP)/Coordinates.cpp \
- $(LCPP)/PointCoordinates.cpp $(LCPP)/Qhull.cpp $(LCPP)/QhullFacet.cpp \
+# CFILESR for reentrant Qhull, ordered alphabetically after libqhull.c
+CFILESR= src/qhull/unix_r.c $(LSR)/libqhull_r.c $(LSR)/geom_r.c $(LSR)/geom2_r.c $(LSR)/global_r.c $(LSR)/io_r.c \
+ $(LSR)/mem_r.c $(LSR)/merge_r.c $(LSR)/poly_r.c $(LSR)/poly2_r.c $(LSR)/random_r.c $(LSR)/rboxlib_r.c \
+ $(LSR)/qset_r.c $(LSR)/stat_r.c $(LSR)/user_r.c $(LSR)/usermem_r.c $(LSR)/userprintf_r.c $(LSR)/userprintf_rbox_r.c \
+ src/qconvex/qconvex_r.c src/qdelaunay/qdelaun_r.c src/qhalf/qhalf_r.c src/qvoronoi/qvoronoi_r.c
+
+# CXXFILES for C++ sources using libqhull_r (reentrant qhull), alphabetical
+CXXFILES= $(LCPP)/Coordinates.cpp $(LCPP)/PointCoordinates.cpp \
+ $(LCPP)/Qhull.cpp $(LCPP)/QhullFacet.cpp \
$(LCPP)/QhullFacetList.cpp $(LCPP)/QhullFacetSet.cpp \
$(LCPP)/QhullHyperplane.cpp $(LCPP)/QhullPoint.cpp \
$(LCPP)/QhullPoints.cpp $(LCPP)/QhullPointSet.cpp $(LCPP)/QhullQh.cpp \
$(LCPP)/QhullRidge.cpp $(LCPP)/QhullSet.cpp $(LCPP)/QhullStat.cpp \
$(LCPP)/QhullVertex.cpp $(LCPP)/QhullVertexSet.cpp $(LCPP)/RboxPoints.cpp \
- $(LCPP)/UsingLibQhull.cpp src/user_eg3/user_eg3.cpp
+ $(LCPP)/RoadError.cpp $(LCPP)/RoadLogEvent.cpp src/user_eg3/user_eg3_r.cpp
-TESTFILES= $(TCPP)/qhulltest.cpp $(TCPP)/Coordinates_test.cpp $(TCPP)/Point_test.cpp $(TCPP)/PointCoordinates_test.cpp \
+# TESTFILES for Qt test of C++ sources using libqhull_r (reentrant qhull), alphabetical after qhulltest.cpp
+TESTFILES= $(TCPP)/qhulltest.cpp $(TCPP)/Coordinates_test.cpp $(TCPP)/PointCoordinates_test.cpp \
$(TCPP)/Qhull_test.cpp $(TCPP)/QhullFacet_test.cpp $(TCPP)/QhullFacetList_test.cpp \
$(TCPP)/QhullFacetSet_test.cpp $(TCPP)/QhullHyperplane_test.cpp $(TCPP)/QhullLinkedList_test.cpp \
$(TCPP)/QhullPoint_test.cpp $(TCPP)/QhullPoints_test.cpp \
$(TCPP)/QhullPointSet_test.cpp $(TCPP)/QhullRidge_test.cpp \
$(TCPP)/QhullSet_test.cpp $(TCPP)/QhullVertex_test.cpp $(TCPP)/QhullVertexSet_test.cpp \
- $(TCPP)/RboxPoints_test.cpp $(TCPP)/UsingLibQhull_test.cpp
+ $(TCPP)/RboxPoints_test.cpp
TXTFILES= Announce.txt REGISTER.txt COPYING.txt README.txt src/Changes.txt
DOCFILES= html/rbox.txt html/qhull.txt
FILES= Makefile src/rbox/rbox.c src/user_eg/user_eg.c src/user_eg2/user_eg2.c \
src/testqset/testqset.c eg/q_test eg/q_egtest eg/q_eg
MANFILES= html/qhull.man html/rbox.man
# Source code is documented by src/libqhull/*.htm
HTMFILES= html/index.htm html/qh-quick.htm html/qh-impre.htm html/qh-eg.htm \
html/qh-optc.htm html/qh-opto.htm html/qh-optf.htm html/qh-optp.htm html/qh-optq.htm \
html/qh-c.htm html/qh-faq.htm html/qhull.htm html/qconvex.htm html/qdelaun.htm \
html/qh-geom.htm html/qh-globa.htm html/qh-io.htm html/qh-mem.htm html/qh-merge.htm \
html/qh-poly.htm html/qh-qhull.htm html/qh-set.htm html/qh-stat.htm html/qh-user.htm \
html/qconvex.htm html/qdelau_f.htm html/qdelaun.htm html/qhalf.htm html/qvoronoi.htm \
html/qvoron_f.htm html/rbox.htm
qhull/unix.o: $(L)/libqhull.h $(L)/user.h $(L)/mem.h
qconvex/qconvex.o: $(L)/libqhull.h $(L)/user.h $(L)/mem.h
qdelanay/qdelaun.o: $(L)/libqhull.h $(L)/user.h $(L)/mem.h
qhalf/qhalf.o: $(L)/libqhull.h $(L)/user.h $(L)/mem.h
qvoronoi/qvoronoi.o: $(L)/libqhull.h $(L)/user.h $(L)/mem.h
$(LS)/libqhull.o: $(LIBQHULL_HDRS)
$(LS)/geom.o: $(LIBQHULL_HDRS)
$(LS)/geom2.o: $(LIBQHULL_HDRS)
$(LS)/global.o: $(LIBQHULL_HDRS)
$(LS)/io.o: $(LIBQHULL_HDRS)
$(LS)/mem.o: $(L)/mem.h
$(LS)/merge.o: $(LIBQHULL_HDRS)
$(LS)/poly.o: $(LIBQHULL_HDRS)
$(LS)/poly2.o: $(LIBQHULL_HDRS)
-$(LS)/random.o: $(L)/libqhull.h $(L)/random.h
+$(LS)/random.o: $(L)/libqhull.h $(L)/random.h $(L)/user.h
$(LS)/rboxlib.o: $(L)/libqhull.h $(L)/random.h $(L)/user.h
$(LS)/qset.o: $(L)/qset.h $(L)/mem.h
$(LS)/stat.o: $(LIBQHULL_HDRS)
$(LS)/user.o: $(LIBQHULL_HDRS)
-$(LSP)/libqhull.o: $(LIBQHULL_HDRS)
-$(LSP)/geom.o: $(LIBQHULL_HDRS)
-$(LSP)/geom2.o: $(LIBQHULL_HDRS)
-$(LSP)/global.o: $(LIBQHULL_HDRS)
-$(LSP)/io.o: $(LIBQHULL_HDRS)
-$(LSP)/mem.o: $(L)/mem.h
-$(LSP)/merge.o: $(LIBQHULL_HDRS)
-$(LSP)/poly.o: $(LIBQHULL_HDRS)
-$(LSP)/poly2.o: $(LIBQHULL_HDRS)
-$(LSP)/random.o: $(L)/libqhull.h $(L)/random.h
-$(LSP)/rboxlib.o: $(L)/libqhull.h $(L)/random.h $(L)/user.h
-$(LSP)/qset.o: $(L)/qset.h $(L)/mem.h
-$(LSP)/stat.o: $(LIBQHULL_HDRS)
-$(LSP)/user.o: $(LIBQHULL_HDRS)
+$(LSR)/libqhull_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/geom_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/geom2_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/global_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/io_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/mem_r.o: $(LR)/mem_r.h
+$(LSR)/merge_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/poly_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/poly2_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/random_r.o: $(LR)/libqhull_r.h $(LR)/random_r.h $(LR)/user_r.h $(LR)/mem_r.h
+$(LSR)/rboxlib_r.o: $(LR)/libqhull_r.h $(LR)/random_r.h $(LR)/user_r.h $(LR)/mem_r.h
+$(LSR)/qset_r.o: $(LR)/qset_r.h $(LR)/mem_r.h
+$(LSR)/stat_r.o: $(LIBQHULLR_HDRS)
+$(LSR)/user_r.o: $(LIBQHULLR_HDRS)
$(LCPP)/RoadError.o: $(LCPP)/RoadError.h $(LCPP)/RoadLogEvent.h
$(LCPP)/RoadLogEvent.o: $(LCPP)/RoadError.h
-$(LCPP)/Coordinates.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/PointCoordinates.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/Qhull.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullFacet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullFacetList.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullFacetSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullHyperplane.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullPoint.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullPoints.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullPointSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullQh.o: $(LIBQHULL_HDRS)
-$(LCPP)/QhullRidge.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullStat.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullVertex.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/QhullVertexSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/RboxPoints.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
-$(LCPP)/UsingLibQhull.o: $(LIBQHULLCPP_HDRS) $(LIBQHULL_HDRS)
+$(LCPP)/Coordinates.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/PointCoordinates.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/Qhull.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullFacet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullFacetList.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullFacetSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullHyperplane.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullPoint.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullPoints.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullPointSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullQh.o: $(LIBQHULLR_HDRS)
+$(LCPP)/QhullRidge.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullStat.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullVertex.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/QhullVertexSet.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
+$(LCPP)/RboxPoints.o: $(LIBQHULLCPP_HDRS) $(LIBQHULLR_HDRS)
.c.o:
$(CC) -c $(CC_OPTS1) -o $@ $<
.cpp.o:
$(CXX) -c $(CXX_OPTS1) -o $@ $<
-# compile qhull without using bin/libqhull.a. Must be after LIBQHULLS_OBJS
-# Same as libqhull/Makefile
+# qhullx -- Compile qhull with using a qhull library. Must be after LIBQHULLS_RBOX_OBJS
+# For qconvex, rbox, and other programs, qhullx produces the same results as libqhull/Makefile
+# For qhull, 'make qhullx' produces the same results as libqhull_r/Makefile
qhullx: src/qconvex/qconvex.o src/qdelaunay/qdelaun.o src/qhalf/qhalf.o \
- src/qvoronoi/qvoronoi.o src/qhull/unix.o src/rbox/rbox.o $(LIBQHULLS_OBJS)
- $(CC) -o bin/qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) src/qconvex/qconvex.o
- $(CC) -o bin/qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) src/qdelaunay/qdelaun.o
- $(CC) -o bin/qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) src/qhalf/qhalf.o
- $(CC) -o bin/qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) src/qvoronoi/qvoronoi.o
- $(CC) -o bin/qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) src/qhull/unix.o
- $(CC) -o bin/rbox $(CC_OPTS2) -lm $(LS)/rboxlib.o $(LS)/random.o $(LS)/usermem.o $(LS)/userprintf_rbox.o src/rbox/rbox.o
+ src/qvoronoi/qvoronoi.o src/rbox/rbox.o \
+ src/qhull/unix_r.o $(LIBQHULLS_RBOX_OBJS) $(LIBQHULLSR_USER_OBJS)
+ $(CC) -o bin/qconvex $(CC_OPTS2) -lm $(LIBQHULLS_USER_OBJS) src/qconvex/qconvex.o
+ $(CC) -o bin/qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_USER_OBJS) src/qdelaunay/qdelaun.o
+ $(CC) -o bin/qhalf $(CC_OPTS2) -lm $(LIBQHULLS_USER_OBJS) src/qhalf/qhalf.o
+ $(CC) -o bin/qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_USER_OBJS) src/qvoronoi/qvoronoi.o
+ $(CC) -o bin/qhull $(CC_OPTS2) -lm $(LIBQHULLSR_USER_OBJS) src/qhull/unix_r.o
+ $(CC) -o bin/rbox $(CC_OPTS2) -lm $(LIBQHULLS_RBOX_OBJS) src/rbox/rbox.o
-bin/rbox D4 | bin/qhull
-# The static library, libqhullstatic, is defined without qh_QHpointer.
+# The static library, libqhullstatic, contains non-reentrant code for Qhull. It is somewhat faster than reentrant libqhullstatic_r
$(LS)/libqhull.o: $(L)/libqhull.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/geom.o: $(L)/geom.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/geom2.o: $(L)/geom2.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/global.o: $(L)/global.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/io.o: $(L)/io.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/mem.o: $(L)/mem.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/merge.o: $(L)/merge.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/poly.o: $(L)/poly.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/poly2.o: $(L)/poly2.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/random.o: $(L)/random.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/rboxlib.o: $(L)/rboxlib.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/qset.o: $(L)/qset.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/stat.o: $(L)/stat.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/user.o: $(L)/user.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/usermem.o: $(L)/usermem.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/userprintf.o: $(L)/userprintf.c
$(CC) -c $(CC_OPTS1) -o $@ $<
$(LS)/userprintf_rbox.o: $(L)/userprintf_rbox.c
$(CC) -c $(CC_OPTS1) -o $@ $<
-# The static library, libqhullstatic_p, is defined with qh_QHpointer (user.h).
-
-$(LSP)/libqhull.o: $(L)/libqhull.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/geom.o: $(L)/geom.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/geom2.o: $(L)/geom2.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/global.o: $(L)/global.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/io.o: $(L)/io.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/mem.o: $(L)/mem.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/merge.o: $(L)/merge.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/poly.o: $(L)/poly.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/poly2.o: $(L)/poly2.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/random.o: $(L)/random.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/rboxlib.o: $(L)/rboxlib.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/qset.o: $(L)/qset.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/stat.o: $(L)/stat.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/user.o: $(L)/user.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/usermem.o: $(L)/usermem.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/userprintf.o: $(L)/userprintf.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-$(LSP)/userprintf_rbox.o: $(L)/userprintf_rbox.c
- $(CC) -c -Dqh_QHpointer $(CC_OPTS1) -o $@ $<
-
-lib/libqhullstatic.a: $(LIBQHULLS_OBJS)
+# The static library, libqhullstatic_r, contains reentrant code with the same behavior as libqhullstatic
+
+$(LSR)/libqhull_r.o: $(LR)/libqhull_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/geom_r.o: $(LR)/geom_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/geom2_r.o: $(LR)/geom2_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/global_r.o: $(LR)/global_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/io_r.o: $(LR)/io_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/mem_r.o: $(LR)/mem_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/merge_r.o: $(LR)/merge_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/poly_r.o: $(LR)/poly_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/poly2_r.o: $(LR)/poly2_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/random_r.o: $(LR)/random_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/rboxlib_r.o: $(LR)/rboxlib_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/qset_r.o: $(LR)/qset_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/stat_r.o: $(LR)/stat_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/user_r.o: $(LR)/user_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/usermem_r.o: $(LR)/usermem_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/userprintf_r.o: $(LR)/userprintf_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+$(LSR)/userprintf_rbox_r.o: $(LR)/userprintf_rbox_r.c
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+
+lib/libqhullstatic.a: $(LIBQHULLS_RBOX_OBJS)
@echo ==========================================
@echo ==== If 'ar' fails, try 'make qhullx' ====
@echo ==========================================
ar -rs $@ $^
#If 'ar -rs' fails try using 'ar -s' with 'ranlib'
#ranlib $@
-lib/libqhullstatic_p.a: $(LIBQHULLSP_OBJS)
+lib/libqhullstatic_r.a: $(LIBQHULLSR_RBOX_OBJS)
ar -rs $@ $^
#ranlib $@
lib/libqhullcpp.a: $(LIBQHULLCPP_OBJS)
ar -rs $@ $^
#ranlib $@
-lib/libqhull.$(SO): $(LIBQHULLS_OBJS)
- $(CC) -shared -o $@ $(CC_OPTS3) $^
- cd lib && ln -f -s libqhull.$(SO) libqhull.so
-
-lib/libqhull_p.$(SO): $(LIBQHULLSP_OBJS)
+lib/libqhull_r.$(SO): $(LIBQHULLSR_RBOX_OBJS)
$(CC) -shared -o $@ $(CC_OPTS3) $^
- cd lib && ln -f -s libqhull_p.$(SO) libqhull_p.so
+ cd lib && ln -f -s libqhull_r.$(SO) libqhull_r.so
# don't use ../qconvex. Does not work on Red Hat Linux
bin/qconvex: src/qconvex/qconvex.o lib/libqhullstatic.a
$(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic -lm
bin/qdelaunay: src/qdelaunay/qdelaun.o lib/libqhullstatic.a
$(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic -lm
bin/qhalf: src/qhalf/qhalf.o lib/libqhullstatic.a
$(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic -lm
bin/qvoronoi: src/qvoronoi/qvoronoi.o lib/libqhullstatic.a
$(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic -lm
-bin/qhull: src/qhull/unix.o lib/libqhullstatic.a
- $(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic -lm
+bin/qhull: src/qhull/unix_r.o lib/libqhullstatic_r.a
+ $(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic_r -lm
-chmod +x eg/q_test eg/q_eg eg/q_egtest
bin/rbox: src/rbox/rbox.o lib/libqhullstatic.a
$(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic -lm
bin/testqset: src/testqset/testqset.o src/libqhull/qset.o src/libqhull/mem.o
$(CC) -o $@ $^ $(CC_OPTS2) -lm
-bin/user_eg: src/user_eg/user_eg.c lib/libqhull_p.$(SO)
+bin/testqset_r: src/testqset_r/testqset_r.o src/libqhull_r/qset_r.o src/libqhull_r/mem_r.o
+ $(CC) -o $@ $^ $(CC_OPTS2) -lm
+
+# You may use -lqhullstatic_r instead of -lqhull_r
+bin/user_eg: src/user_eg/user_eg_r.o lib/libqhull_r.$(SO)
@echo -e '\n\n==================================================='
- @echo -e '== If user_eg fails on MinGW or Cygwin, use'
- @echo -e '== "make SO=dll" and copy lib/libqhull_p.dll to bin/'
- @echo -e '== If user_eg fails to link, switch to -lqhullstatic_p'
+ @echo -e '== If user_eg fails to link on MinGW or Cygwin, use'
+ @echo -e '== "make SO=dll" and copy lib/libqhull_r.dll to bin/'
+ @echo -e '== Otherwise if user_eg fails to link, switch to -lqhullstatic_r'
@echo -e '===================================================\n'
- $(CC) -o $@ $< -Dqh_QHpointer $(CC_OPTS1) $(CC_OPTS3) -Llib -lqhull_p -lm
+ $(CC) -o $@ $< $(CC_OPTS1) $(CC_OPTS3) -Llib -lqhull_r -lm
-# You may use -lqhullstatic instead of -lqhull
-bin/user_eg2: src/user_eg2/user_eg2.o lib/libqhull.$(SO)
+bin/user_eg2: src/user_eg2/user_eg2_r.o lib/libqhullstatic_r.a
@echo -e '\n\n==================================================='
- @echo -e '== If user_eg2 fails on MinGW or Cygwin, use'
- @echo -e '== "make SO=dll" and copy lib/libqhull.dll to bin/'
- @echo -e '== If user_eg2 fails to link, switch to -lqhullstatic'
+ @echo -e '== user_eg2 links to qhullstatic_r. It may use libqhull_r instead.'
@echo -e '===================================================\n'
- $(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhull -lm
+ $(CC) -o $@ $< $(CC_OPTS2) -Llib -lqhullstatic_r -lm
-bin/user_eg3: src/user_eg3/user_eg3.o lib/libqhullstatic_p.a lib/libqhullcpp.a
- $(CXX) -o $@ $< $(CXX_OPTS2) -Llib -lqhullcpp -lqhullstatic_p -lm
+bin/user_eg3: src/user_eg3/user_eg3_r.o lib/libqhullstatic_r.a lib/libqhullcpp.a
+ $(CXX) -o $@ $< $(CXX_OPTS2) -Llib -lqhullcpp -lqhullstatic_r -lm
# end of Makefile
diff --git a/README.txt b/README.txt
index 12abb36..eb4f853 100644
--- a/README.txt
+++ b/README.txt
@@ -1,540 +1,548 @@
Name
- qhull, rbox 2012.1 2012/02/18
+ qhull, rbox 2015.0.2 2015/08/30
Convex hull, Delaunay triangulation, Voronoi diagrams, Halfspace intersection
Documentation:
html/index.htm
http://www.qhull.org/html
Available from:
<http://www.qhull.org>
<git@gitorious.org:qhull/qhull.git>
- <http://packages.debian.org/sid/libqhull5> [out-of-date]
News and a paper:
<http://www.qhull.org/news>
<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405>
Version 1 (simplicial only):
<http://www.qhull.org/download/qhull-1.0.tar.gz>
-
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. <http://www.geomview.org>
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 Nokia's Qt Framework. Qhull's C++ interface may change without
+ 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 contribute to Qhull
- Qhull is on Gitorious (http://gitorious.org:qhull, git@gitorious.org:qhull/qhull.git)
+ Qhull is on Gitorious
+ (http://gitorious.org:qhull, git@gitorious.org:qhull/qhull.git)
For internal documentation, see html/qh-code.htm
To install Qhull
- Qhull is precompiled for Windows, otherwise it needs compilation.
+ Qhull is precompiled for Windows 32-bit, otherwise it needs compilation.
Besides makefiles for gcc, qhull includes CMakeLists.txt for CMake,
vcproj/sln files for Microsoft Visual Studio, and .pro files for Qt Creator.
It compiles with mingw.
Install and build instructions follow.
See the end of this document for a list of distributed files.
-----------------
-Installing Qhull on Windows 7 (32- or 64-bit), Windows XP, and Windows NT
+Installing Qhull on Windows 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.
To install Qhull:
- Unzip the files into a directory. You may use WinZip32 <www.hotfiles.com>
- 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 and error output to stdout
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 MSYS (www.mingw.org),
+ If you use qhull a lot, install 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
- - Extract Qhull from qhull...tgz or qhull...zip
+ - Download and extract Qhull (either gitorious or the .tgz or .zip file)
- make
- export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH
Or, to build Qhull and libqhullstatic.a
- Extract Qhull from qhull...tgz or qhull...zip
- cd src/libqhull
- make
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.
+
-----------------
Installing Qhull with CMake 2.6 or later
To build Qhull, static libraries, shared library, and C++ interface
- - Extract Qhull from qhull...tgz or qhull...zip
+ - Download and extract Qhull (either gitorious or the .tgz or .zip file)
- cd build
+ - cmake --help # List build generators
+ - make -G "<generator>" .. && cmake ..
- cmake ..
- make
- make install
On Windows, CMake installs to C:/Program Files/qhull
See CMakeLists.txt for further build instructions
-----------------
Installing Qhull with Qt
- To build Qhull, static libraries, shared library, C++ interface, and C++ test
- - Extract Qhull from qhull...tgz or qhull...zip
- - cd src
- - qmake
- - make
-
------------------
-Installing Qhull with Autoconf [WARNING out-of-date]
+ To build Qhull, including its C++ test (qhulltest)
+ - Download and extract Qhull (either gitorious or the .tgz or .zip file)
+ - Load src/qhull-all.pro into QtCreator
+ - Build
- The tar.gz tarball contains documentation, source files,
- and a config directory [R. Laboissiere].
+-------------------
+Working with Qhull's C++ interface
- [Nov 2011] Qhull 2009.1.2 does not include the C++ interface
+ See html/qh-code.htm#cpp for calling Qhull from C++ programs
- To install Qhull
- - Extract the files
- - ./configure
- - make
- - make install
+ See html/qh-code.htm#reentrant for converting from Qhull-2012
--------------------
-Working with Qhull's C++ interface
+ Examples of using the C++ interface
+ user_eg3_r.cpp
+ qhulltest/*_test.cpp
Qhull's C++ interface is likely to change. Stay current with Gitorious.
To clone Qhull's next branch from http://gitorious.org/qhull
git init
git clone git://gitorious.org/qhull/qhull.git
cd qhull
git checkout next
...
git pull origin next
- Examples of using the C++ interface
- user_eg3.cpp
- qhulltest/*_test.cpp
-
- Compile qhullcpp and libqhullr with the same compiler. These libraries use the
- C routines setjmp() and longjmp() for error handling. They must be compiled with the
- same compiler.
+ Compile qhullcpp and libqhull_r with the same compiler. These 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 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.
+
+ The new, reentrant 'C' code (src/libqhullr), 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.
+
------------------
-Compiling Qhull with Microsoft Visual C++ 2005 or later
+Compiling Qhull with Microsoft Visual C++
To compile Qhull with Microsoft Visual C++
- - Extract Qhull from Gitorious, qhull...tgz, or qhull...zip
+ - Download and extract Qhull (either gitorious or the .tgz or .zip file)
- Load solution build/qhull.sln
- - Build
- - Project qhulltest requires Qt for DevStudio (http://qt.nokia.com/downloads)
+ - 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 incorrect, precompile will fail with 'Can not locate the file specified'
-
+ If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified'
+
+ Notes:
+ - For 64-bit builds
+ Generate sln and vcproj files with Cmake and the 'Win64' tag (see CMakelists.txt)
+ - For Microsoft Visual C++ 2012
+ The prepackaged sln and vproj files do not upgrade cleanly
+ - For 32-bit builds, the conversion works OK but it reports a warning
+ You can use Cmake to generate sln and vcproj files (see CMakelists.txt)
+
-----------------
Compiling Qhull with Qt Creator
- Qt (http://qt.nokia.com) is a C++ framework for Windows, Linux, and Macintosh
+ Qt (http://www.qt.io) is a C++ framework for Windows, Linux, and Macintosh
Qhull uses QTestLib to test qhull's C++ interface (qhulltest)
To compile Qhull with Qt Creator
- - Extract Qhull from Gitorious, qhull...tgz, or qhull...zip
- - Download the Qt SDK from Nokia (http://qt.nokia.com/downloads)
+ - Download and extract Qhull (either gitorious or the .tgz 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
- - Extract Qhull from Gitorious, qhull...tgz, or qhull...zip
+ - Download and extract Qhull (either gitorious or the .tgz or .zip file)
- Install Road Bash (http://www.qhull.org/bash)
or install MSYS (http://www.mingw.org/wiki/msys)
- - Install MINGW (http://www.mingw.org/). Mingw is included with Qt SDK.
+ - 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
- - Extract Qhull from Gitorious, qhull...tgz, or qhull...zip
+ - Download and extract Qhull (either gitorious or the .tgz 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 gzip file
+ To unpack the tgz file
- tar zxf qhull-src.tgz
- cd qhull
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
+ - 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 compiles with Borland C++ 5.0 bcc32. A Makefile is included.
Execute 'make -f Mborland'. If you use the Borland IDE, set the ANSI
option in Options:Project:Compiler:Source:Language-compliance.
Qhull compiles with Borland C++ 4.02 for Win32 and DOS Power Pack.
Use 'make -f Mborland -D_DPMI'. Qhull 1.0 compiles with Borland
C++ 4.02. For rbox 1.0, use "bcc32 -WX -w- -O2-e -erbox -lc rbox.c".
Use the same options for Qhull 1.0. [D. Zwick]
Qhull compiles with Metrowerks C++ 1.7 with the ANSI option.
If you turn on full warnings, the compiler will report a number of
unused variables, variables set but not used, and dead code. These are
intentional. For example, variables may be initialized (unnecessarily)
to prevent warnings about possible use of uninitialized variables.
Qhull compiles on the Power Macintosh with Metrowerk's C compiler.
It uses the SIOUX interface to read point coordinates and return output.
There is no graphical output. For project files, see 'Compiling a
custom build'. Instead of using SIOUX, Qhull may be embedded within an
application.
Some users have reported problems with compiling Qhull under Irix 5.1. It
compiles under other versions of Irix.
If you have troubles with the memory manager, you can turn it off by
defining qh_NOmem in mem.h.
-----------------
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)
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)
+ bin/* // Qhull executables and dll (.zip only)
build/qhull.sln // DevStudio solution and project files (2005 or later)
build/*.vcproj
- config/* // Autoconf files for creating configure (Unix only)
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)
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):
- qhull.exe // Win32 executables and dlls (.zip only)
- qconvex.exe
+ 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.dll
- qhull_p.dll
+ 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 only)
+ msvcr80.dll // Visual C++ redistributable file (.zip download only)
src/
- qhullr/unix_r.c // Qhull and rbox applications using libqhullstatic_r.a
- rboxr/rbox_r.c
- qhull/unix.c // Qhull and rbox applications
+ 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
- rbox/rbox.c
- user_eg/user_eg.c // example of using qhull_r.dll
- user_eg2/user_eg2.c // example of using qhull.dll from a user program
- user_eg3/user_eg3.cpp // example of Qhull's C++ interface with libqhullstatic_r.a
+ 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 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/testqset.c // Test of qset_r.c and mem_r.c
+ 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
- user_eg7/user_eg7.c // example of using deprecated qhull_p.dll (requires -Dqh_QHpointer)
- user_eg8/user_eg8.c // example of using deprecated qhull.dll from a user program
- user_eg9/user_eg9.cpp // example of Qhull's deprecated C++ interface with libqhullstatic_p.a
- qhullptest/qhullptest.cpp // Test of Qhull's deprecated C++ interface with libqhullstatic_p.a
- testqsetp/testqsetp.c // Test of deprecated qset.c and mem.c
src/libqhull
- libqhull.pro // Qt project for shared library (qhull.dll)
+ 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/libqhullp
- libqhullp.pro // Qt project for shared library (qhull_p.dll)
- qhull_p-exports.def // Export Definition file for Visual C++
-
src/libqhullstatic/
- libqhullstatic.pro // Qt project for static library
-
-src/libqhullstaticp/
- libqhullstaticp.pro // Qt project for static library with qh_QHpointer
+ libqhullstatic.pro // Qt project for non-reentrant, static library
src/libqhullcpp/
- libqhullcpp.pro // Qt project for static C++ library
+ libqhullcpp.pro // Qt project for renentrant, static C++ library
Qhull.cpp // Call libqhull.c from C++
Qhull.h
qt-qhull.cpp // Supporting methods for Qt
- qhull_interface.cpp // Another approach to C++
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
QhullStat.cpp
QhullStat.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
QhullRidge.cpp
QhullRidge.h
QhullSet.cpp
QhullSet.h
QhullSets.h
QhullVertexSet.cpp
QhullVertexSet.h
functionObjects.h // supporting classes
QhullError.cpp
QhullError.h
QhullQh.cpp
QhullQh.h
UsingLibQhull.cpp
UsingLibQhull.h
src/qhulltest/
qhulltest.pro // Qt project for test of C++ interface
Coordinates_test.cpp // Test of each class
PointCoordinates_test.cpp
- Point_test.cpp
+ Qhull_test.cpp
+ QhullFacet_test.cpp
QhullFacetList_test.cpp
QhullFacetSet_test.cpp
- QhullFacet_test.cpp
QhullHyperplane_test.cpp
QhullLinkedList_test.cpp
- QhullPointSet_test.cpp
- QhullPoints_test.cpp
QhullPoint_test.cpp
+ QhullPoints_test.cpp
+ QhullPointSet_test.cpp
QhullRidge_test.cpp
QhullSet_test.cpp
- QhullVertexSet_test.cpp
QhullVertex_test.cpp
- Qhull_test.cpp
+ QhullVertexSet_test.cpp
RboxPoints_test.cpp
UsingLibQhull_test.cpp
src/road/
RoadError.cpp // Supporting base classes
RoadError.h
RoadLogEvent.cpp
RoadLogEvent.h
RoadTest.cpp // Run multiple test files with QTestLib
RoadTest.h
-src/testqset/
- testqset.pro // Qt project for test qset.c with mem.c
- testqset.c
-
-----------------
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/build/libqhull.vcproj b/build/libqhull.vcproj
index ca73a51..d4260c0 100644
--- a/build/libqhull.vcproj
+++ b/build/libqhull.vcproj
@@ -1,545 +1,354 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="libqhull"
- ProjectGUID="{5D02D0DA-335E-33A3-A3B2-0746F1C0E068}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{325DAFCC-0151-4B12-B5FC-E976AE866ACA}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="libqhull.dir\Debug"
ConfigurationType="2"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;libqhull_EXPORTS"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;libqhull_EXPORTS"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qhull_EXPORTS"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull_d.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\qhull_d.dll"
- Version="6.3"
+ Version="7.0"
LinkIncremental="1"
- AdditionalLibraryDirectories=""
ModuleDefinitionFile="..\src\libqhull\qhull-exports.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="..\lib\qhull_d.pdb"
- ImportLibrary="..\lib\qhull_d.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull.pdb"
+ GenerateDebugInformation="TRUE"
+ ImportLibrary="..\lib\qhull_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="libqhull.dir\Release"
ConfigurationType="2"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;libqhull_EXPORTS"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;libqhull_EXPORTS"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_EXPORTS"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\qhull.dll"
- Version="6.3"
+ Version="7.0"
LinkIncremental="1"
- AdditionalLibraryDirectories=""
ModuleDefinitionFile="..\src\libqhull\qhull-exports.def"
- ProgramDatabaseFile="..\lib\qhull.pdb"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull.pdb"
+ ImportLibrary="..\lib\qhull.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="libqhull.dir\MinSizeRel"
ConfigurationType="2"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;libqhull_EXPORTS"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;libqhull_EXPORTS"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_EXPORTS"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\qhull.dll"
- Version="6.3"
+ Version="7.0"
LinkIncremental="1"
- AdditionalLibraryDirectories=""
ModuleDefinitionFile="..\src\libqhull\qhull-exports.def"
- ProgramDatabaseFile="..\lib\qhull.pdb"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull.pdb"
+ ImportLibrary="..\lib\qhull.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="libqhull.dir\RelWithDebInfo"
ConfigurationType="2"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;libqhull_EXPORTS"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;libqhull_EXPORTS"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_EXPORTS"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\qhull.dll"
- Version="6.3"
+ Version="7.0"
LinkIncremental="1"
- AdditionalLibraryDirectories=""
ModuleDefinitionFile="..\src\libqhull\qhull-exports.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="..\lib\qhull.pdb"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull.pdb"
+ GenerateDebugInformation="TRUE"
+ ImportLibrary="..\lib\qhull.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\libqhull\geom.c"
- >
+ RelativePath="..\src\libqhull\global.c">
</File>
<File
- RelativePath="..\src\libqhull\geom2.c"
- >
+ RelativePath="..\src\libqhull\stat.c">
</File>
<File
- RelativePath="..\src\libqhull\global.c"
- >
+ RelativePath="..\src\libqhull\geom2.c">
</File>
<File
- RelativePath="..\src\libqhull\io.c"
- >
+ RelativePath="..\src\libqhull\poly2.c">
</File>
<File
- RelativePath="..\src\libqhull\libqhull.c"
- >
+ RelativePath="..\src\libqhull\merge.c">
</File>
<File
- RelativePath="..\src\libqhull\mem.c"
- >
+ RelativePath="..\src\libqhull\libqhull.c">
</File>
<File
- RelativePath="..\src\libqhull\merge.c"
- >
+ RelativePath="..\src\libqhull\geom.c">
</File>
<File
- RelativePath="..\src\libqhull\poly.c"
- >
+ RelativePath="..\src\libqhull\poly.c">
</File>
<File
- RelativePath="..\src\libqhull\poly2.c"
- >
+ RelativePath="..\src\libqhull\qset.c">
</File>
<File
- RelativePath="..\src\libqhull\qhull-exports.def"
- >
+ RelativePath="..\src\libqhull\mem.c">
</File>
<File
- RelativePath="..\src\libqhull\qset.c"
- >
+ RelativePath="..\src\libqhull\random.c">
</File>
<File
- RelativePath="..\src\libqhull\random.c"
- >
+ RelativePath="..\src\libqhull\usermem.c">
</File>
<File
- RelativePath="..\src\libqhull\rboxlib.c"
- >
+ RelativePath="..\src\libqhull\userprintf.c">
</File>
<File
- RelativePath="..\src\libqhull\stat.c"
- >
+ RelativePath="..\src\libqhull\io.c">
</File>
<File
- RelativePath="..\src\libqhull\user.c"
- >
+ RelativePath="..\src\libqhull\user.c">
</File>
<File
- RelativePath="..\src\libqhull\usermem.c"
- >
+ RelativePath="..\src\libqhull\rboxlib.c">
</File>
<File
- RelativePath="..\src\libqhull\userprintf.c"
- >
+ RelativePath="..\src\libqhull\userprintf_rbox.c">
</File>
<File
- RelativePath="..\src\libqhull\userprintf_rbox.c"
- >
+ RelativePath="..\src\libqhull\qhull-exports.def">
</File>
</Filter>
<Filter
Name="Header Files"
- >
+ Filter="">
<File
- RelativePath="..\src\libqhull\geom.h"
- >
+ RelativePath="..\src\libqhull\libqhull.h">
</File>
<File
- RelativePath="..\src\libqhull\io.h"
- >
+ RelativePath="..\src\libqhull\geom.h">
</File>
<File
- RelativePath="..\src\libqhull\libqhull.h"
- >
+ RelativePath="..\src\libqhull\io.h">
</File>
<File
- RelativePath="..\src\libqhull\mem.h"
- >
+ RelativePath="..\src\libqhull\mem.h">
</File>
<File
- RelativePath="..\src\libqhull\merge.h"
- >
+ RelativePath="..\src\libqhull\merge.h">
</File>
<File
- RelativePath="..\src\libqhull\poly.h"
- >
+ RelativePath="..\src\libqhull\poly.h">
</File>
<File
- RelativePath="..\src\libqhull\qhull_a.h"
- >
+ RelativePath="..\src\libqhull\qhull_a.h">
</File>
<File
- RelativePath="..\src\libqhull\qset.h"
- >
+ RelativePath="..\src\libqhull\qset.h">
</File>
<File
- RelativePath="..\src\libqhull\random.h"
- >
+ RelativePath="..\src\libqhull\random.h">
</File>
<File
- RelativePath="..\src\libqhull\stat.h"
- >
+ RelativePath="..\src\libqhull\stat.h">
</File>
<File
- RelativePath="..\src\libqhull\user.h"
- >
+ RelativePath="..\src\libqhull\user.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/libqhull_p.vcproj b/build/libqhull_p.vcproj
deleted file mode 100644
index 6ea27f4..0000000
--- a/build/libqhull_p.vcproj
+++ /dev/null
@@ -1,545 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="libqhull_p"
- ProjectGUID="{1631434A-D3A9-4015-B42F-D3CA6015915A}"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="libqhull_p.dir\Debug"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer;qhull_EXPORTS"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull_pd.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkLibraryDependencies="false"
- AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
- OutputFile="..\bin\qhull_pd.dll"
- Version="6.3"
- LinkIncremental="1"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile="..\src\libqhullp\qhull_p-exports.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="..\lib\qhull_pd.pdb"
- ImportLibrary="..\lib\qhull_pd.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="libqhull_p.dir\Release"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_EXPORTS"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull_p.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkLibraryDependencies="false"
- AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
- OutputFile="..\bin\qhull_p.dll"
- Version="6.3"
- LinkIncremental="1"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile="..\src\libqhullp\qhull_p-exports.def"
- ProgramDatabaseFile="..\lib\qhull_p.pdb"
- ImportLibrary="..\lib\qhull_p.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="MinSizeRel|Win32"
- OutputDirectory="MinSizeRel"
- IntermediateDirectory="libqhull_p.dir\MinSizeRel"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_EXPORTS"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull_p.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkLibraryDependencies="false"
- AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
- OutputFile="..\bin\qhull_p.dll"
- Version="6.3"
- LinkIncremental="1"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile="..\src\libqhullp\qhull_p-exports.def"
- ProgramDatabaseFile="..\lib\qhull_p.pdb"
- ImportLibrary="..\lib\qhull_p.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="RelWithDebInfo|Win32"
- OutputDirectory="RelWithDebInfo"
- IntermediateDirectory="libqhull_p.dir\RelWithDebInfo"
- ConfigurationType="2"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_EXPORTS"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhull_p.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_EXPORTS"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkLibraryDependencies="false"
- AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
- OutputFile="..\bin\qhull_p.dll"
- Version="6.3"
- LinkIncremental="1"
- AdditionalLibraryDirectories=""
- ModuleDefinitionFile="..\src\libqhullp\qhull_p-exports.def"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="..\lib\qhull_p.pdb"
- ImportLibrary="..\lib\qhull_p.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- >
- <File
- RelativePath="..\src\libqhull\geom.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\geom2.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\global.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\io.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\libqhull.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\mem.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\merge.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\poly.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\poly2.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhullp\qhull_p-exports.def"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\qset.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\random.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\rboxlib.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\stat.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\user.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\usermem.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\userprintf.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\userprintf_rbox.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- >
- <File
- RelativePath="..\src\libqhull\geom.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\io.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\libqhull.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\mem.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\merge.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\poly.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\qhull_a.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\qset.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\random.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\stat.h"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\user.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/build/qconvex.vcproj b/build/qconvex.vcproj
index 5a461bb..24e026e 100644
--- a/build/qconvex.vcproj
+++ b/build/qconvex.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qconvex"
- ProjectGUID="{D704D132-A90A-4EBE-8B58-DE533416DA4A}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{54DAEE1F-3E94-4759-91C2-C8BE355DC339}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qconvex.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qconvex.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qconvex.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_d.lib "
OutputFile="..\bin\qconvex.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qconvex.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qconvex.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qconvex_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qconvex.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qconvex.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qconvex.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qconvex.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qconvex.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qconvex.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qconvex.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qconvex.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qconvex.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qconvex.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qconvex.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qconvex.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qconvex.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qconvex.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qconvex.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qconvex.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qconvex.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qconvex.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qconvex.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qconvex.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qconvex.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\qconvex\qconvex.c"
- >
+ RelativePath="..\src\qconvex\qconvex.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/qdelaunay.vcproj b/build/qdelaunay.vcproj
index dd5c5ec..985ebd1 100644
--- a/build/qdelaunay.vcproj
+++ b/build/qdelaunay.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qdelaunay"
- ProjectGUID="{65DE86BB-E848-4C2D-A779-EB3EBCA39190}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{BC76A867-82E4-4450-B23A-EE0B1D651618}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qdelaunay.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_d.lib "
OutputFile="..\bin\qdelaunay.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qdelaunay.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qdelaunay.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qdelaunay_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qdelaunay.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qdelaunay.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qdelaunay.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qdelaunay.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qdelaunay.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qdelaunay.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qdelaunay.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qdelaunay.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qdelaunay.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qdelaunay.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qdelaunay.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qdelaunay.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qdelaunay.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qdelaunay.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qdelaunay.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qdelaunay.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\qdelaunay\qdelaun.c"
- >
+ RelativePath="..\src\qdelaunay\qdelaun.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/qhalf.vcproj b/build/qhalf.vcproj
index db5a92e..7b4a6c3 100644
--- a/build/qhalf.vcproj
+++ b/build/qhalf.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qhalf"
- ProjectGUID="{E285DCA5-FC4C-47B3-B495-A01667E3187A}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{363FBD97-FD1B-4DFA-A6A1-8C76385816DE}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qhalf.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhalf.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhalf.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_d.lib "
OutputFile="..\bin\qhalf.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qhalf.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qhalf.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhalf_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qhalf.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhalf.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhalf.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qhalf.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qhalf.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qhalf.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhalf.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qhalf.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhalf.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhalf.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qhalf.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qhalf.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qhalf.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhalf.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qhalf.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhalf.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhalf.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qhalf.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qhalf.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qhalf.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhalf.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\qhalf\qhalf.c"
- >
+ RelativePath="..\src\qhalf\qhalf.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/qhull.sln b/build/qhull.sln
index af2428a..2892b92 100644
--- a/build/qhull.sln
+++ b/build/qhull.sln
@@ -1,203 +1,223 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qconvex", "qconvex.vcproj", "{D704D132-A90A-4EBE-8B58-DE533416DA4A}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libqhull", "libqhull.vcproj", "{325DAFCC-0151-4B12-B5FC-E976AE866ACA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qconvex", "qconvex.vcproj", "{54DAEE1F-3E94-4759-91C2-C8BE355DC339}"
ProjectSection(ProjectDependencies) = postProject
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947} = {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA} = {1B932C34-DE95-4A60-A50D-4EB702BC97AA}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qdelaunay", "qdelaunay.vcproj", "{65DE86BB-E848-4C2D-A779-EB3EBCA39190}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qdelaunay", "qdelaunay.vcproj", "{BC76A867-82E4-4450-B23A-EE0B1D651618}"
ProjectSection(ProjectDependencies) = postProject
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947} = {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA} = {1B932C34-DE95-4A60-A50D-4EB702BC97AA}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhalf", "qhalf.vcproj", "{E285DCA5-FC4C-47B3-B495-A01667E3187A}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhalf", "qhalf.vcproj", "{363FBD97-FD1B-4DFA-A6A1-8C76385816DE}"
ProjectSection(ProjectDependencies) = postProject
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947} = {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA} = {1B932C34-DE95-4A60-A50D-4EB702BC97AA}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhull", "qhull.vcproj", "{0BDDB82D-3246-41E1-8691-9205CF705BFA}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhull", "qhull.vcproj", "{7AACF1DE-2A08-493F-9B09-218597BB9A57}"
ProjectSection(ProjectDependencies) = postProject
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947} = {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640} = {80A8E252-E760-4D8A-86E5-F32ECA1B8640}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libqhull", "libqhull.vcproj", "{5D02D0DA-335E-33A3-A3B2-0746F1C0E068}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhull_p", "qhull_p.vcproj", "{E8734A27-2205-460C-849C-5B8FC95E9EBC}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libqhull_p", "libqhull_p.vcproj", "{1631434A-D3A9-4015-B42F-D3CA6015915A}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhull_r", "qhull_r.vcproj", "{D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullcpp", "qhullcpp.vcproj", "{2C448FFE-CDF6-4639-BB23-39588F006C73}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullcpp", "qhullcpp.vcproj", "{B49E4038-0F40-494F-94D8-1CA30D8241A0}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullstatic", "qhullstatic.vcproj", "{3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullstatic", "qhullstatic.vcproj", "{1B932C34-DE95-4A60-A50D-4EB702BC97AA}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullstatic_p", "qhullstatic_p.vcproj", "{4730C632-C24E-40E4-AF42-80F6C6226048}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullstatic_r", "qhullstatic_r.vcproj", "{80A8E252-E760-4D8A-86E5-F32ECA1B8640}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qvoronoi", "qvoronoi.vcproj", "{52135D45-9834-475A-9E4D-12852711A714}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qvoronoi", "qvoronoi.vcproj", "{71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}"
ProjectSection(ProjectDependencies) = postProject
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947} = {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA} = {1B932C34-DE95-4A60-A50D-4EB702BC97AA}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rbox", "rbox.vcproj", "{887E64E6-D850-4B31-8E06-66E5B7E92F6D}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rbox", "rbox.vcproj", "{253F7FE0-0402-460C-8D9C-51A5E998A0B5}"
ProjectSection(ProjectDependencies) = postProject
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947} = {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA} = {1B932C34-DE95-4A60-A50D-4EB702BC97AA}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg", "user_eg.vcproj", "{ACC05378-EF76-436F-A33D-F0A1AB916326}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testqset", "testqset.vcproj", "{C019AD4E-D7BB-4EAB-B277-DB4FCD502383}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testqset_r", "testqset_r.vcproj", "{54CA28AA-178A-411D-99DC-E6FD8F117C70}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg", "user_eg.vcproj", "{D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}"
ProjectSection(ProjectDependencies) = postProject
- {1631434A-D3A9-4015-B42F-D3CA6015915A} = {1631434A-D3A9-4015-B42F-D3CA6015915A}
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3} = {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg2", "user_eg2.vcproj", "{84EB3982-1012-49E9-975E-BFD2F0D312C2}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg2", "user_eg2.vcproj", "{36ED9747-183D-4411-86AB-F0E6F775D3C0}"
ProjectSection(ProjectDependencies) = postProject
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068} = {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640} = {80A8E252-E760-4D8A-86E5-F32ECA1B8640}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg3", "user_eg3.vcproj", "{7668C45C-60AA-457C-BA91-4F94AAB6A540}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg3", "user_eg3.vcproj", "{F3356B1C-361D-48AD-9042-9B115EE536E3}"
ProjectSection(ProjectDependencies) = postProject
- {2C448FFE-CDF6-4639-BB23-39588F006C73} = {2C448FFE-CDF6-4639-BB23-39588F006C73}
- {4730C632-C24E-40E4-AF42-80F6C6226048} = {4730C632-C24E-40E4-AF42-80F6C6226048}
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640} = {80A8E252-E760-4D8A-86E5-F32ECA1B8640}
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0} = {B49E4038-0F40-494F-94D8-1CA30D8241A0}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhulltest", "qhulltest.vcproj", "{E12E04D0-C11C-36C0-950E-A203DCBFB37C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhulltest", "qhulltest\qhulltest.vcproj", "{E12E04D0-C11C-36C0-950E-A203DCBFB37C}"
ProjectSection(ProjectDependencies) = postProject
- {2C448FFE-CDF6-4639-BB23-39588F006C73} = {2C448FFE-CDF6-4639-BB23-39588F006C73}
- {4730C632-C24E-40E4-AF42-80F6C6226048} = {4730C632-C24E-40E4-AF42-80F6C6226048}
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0} = {B49E4038-0F40-494F-94D8-1CA30D8241A0}
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640} = {80A8E252-E760-4D8A-86E5-F32ECA1B8640}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testqset", "testqset.vcproj", "{C9E3DBF2-AA34-3900-9761-5A846CAB6397}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
MinSizeRel|Win32 = MinSizeRel|Win32
Release|Win32 = Release|Win32
RelWithDebInfo|Win32 = RelWithDebInfo|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.Debug|Win32.ActiveCfg = Debug|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.Debug|Win32.Build.0 = Debug|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.Release|Win32.ActiveCfg = Release|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.Release|Win32.Build.0 = Release|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {D704D132-A90A-4EBE-8B58-DE533416DA4A}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.Debug|Win32.ActiveCfg = Debug|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.Debug|Win32.Build.0 = Debug|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.Release|Win32.ActiveCfg = Release|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.Release|Win32.Build.0 = Release|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {65DE86BB-E848-4C2D-A779-EB3EBCA39190}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.Debug|Win32.ActiveCfg = Debug|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.Debug|Win32.Build.0 = Debug|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.Release|Win32.ActiveCfg = Release|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.Release|Win32.Build.0 = Release|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {E285DCA5-FC4C-47B3-B495-A01667E3187A}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.Debug|Win32.ActiveCfg = Debug|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.Debug|Win32.Build.0 = Debug|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.Release|Win32.ActiveCfg = Release|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.Release|Win32.Build.0 = Release|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {0BDDB82D-3246-41E1-8691-9205CF705BFA}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.Debug|Win32.ActiveCfg = Debug|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.Debug|Win32.Build.0 = Debug|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.Release|Win32.ActiveCfg = Release|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.Release|Win32.Build.0 = Release|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {5D02D0DA-335E-33A3-A3B2-0746F1C0E068}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.Debug|Win32.ActiveCfg = Debug|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.Debug|Win32.Build.0 = Debug|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.Release|Win32.ActiveCfg = Release|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.Release|Win32.Build.0 = Release|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {1631434A-D3A9-4015-B42F-D3CA6015915A}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.Debug|Win32.ActiveCfg = Debug|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.Debug|Win32.Build.0 = Debug|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.Release|Win32.ActiveCfg = Release|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.Release|Win32.Build.0 = Release|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {2C448FFE-CDF6-4639-BB23-39588F006C73}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.Debug|Win32.ActiveCfg = Debug|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.Debug|Win32.Build.0 = Debug|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.Release|Win32.ActiveCfg = Release|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.Release|Win32.Build.0 = Release|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.Debug|Win32.ActiveCfg = Debug|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.Debug|Win32.Build.0 = Debug|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.Release|Win32.ActiveCfg = Release|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.Release|Win32.Build.0 = Release|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {4730C632-C24E-40E4-AF42-80F6C6226048}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.Debug|Win32.ActiveCfg = Debug|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.Debug|Win32.Build.0 = Debug|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.Release|Win32.ActiveCfg = Release|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.Release|Win32.Build.0 = Release|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {52135D45-9834-475A-9E4D-12852711A714}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.Debug|Win32.ActiveCfg = Debug|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.Debug|Win32.Build.0 = Debug|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.Release|Win32.ActiveCfg = Release|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.Release|Win32.Build.0 = Release|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {887E64E6-D850-4B31-8E06-66E5B7E92F6D}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.Debug|Win32.ActiveCfg = Debug|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.Debug|Win32.Build.0 = Debug|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.Release|Win32.ActiveCfg = Release|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.Release|Win32.Build.0 = Release|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {ACC05378-EF76-436F-A33D-F0A1AB916326}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.Debug|Win32.ActiveCfg = Debug|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.Debug|Win32.Build.0 = Debug|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.Release|Win32.ActiveCfg = Release|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.Release|Win32.Build.0 = Release|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {84EB3982-1012-49E9-975E-BFD2F0D312C2}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.Debug|Win32.ActiveCfg = Debug|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.Debug|Win32.Build.0 = Debug|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.Release|Win32.ActiveCfg = Release|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.Release|Win32.Build.0 = Release|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {7668C45C-60AA-457C-BA91-4F94AAB6A540}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.Debug|Win32.Build.0 = Debug|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.Release|Win32.ActiveCfg = Release|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.Release|Win32.Build.0 = Release|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {325DAFCC-0151-4B12-B5FC-E976AE866ACA}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.Debug|Win32.ActiveCfg = Debug|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.Debug|Win32.Build.0 = Debug|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.Release|Win32.ActiveCfg = Release|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.Release|Win32.Build.0 = Release|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {54DAEE1F-3E94-4759-91C2-C8BE355DC339}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.Debug|Win32.Build.0 = Debug|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.Release|Win32.ActiveCfg = Release|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.Release|Win32.Build.0 = Release|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {BC76A867-82E4-4450-B23A-EE0B1D651618}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.Debug|Win32.Build.0 = Debug|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.Release|Win32.ActiveCfg = Release|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.Release|Win32.Build.0 = Release|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {363FBD97-FD1B-4DFA-A6A1-8C76385816DE}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.Debug|Win32.Build.0 = Debug|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.Release|Win32.ActiveCfg = Release|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.Release|Win32.Build.0 = Release|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {7AACF1DE-2A08-493F-9B09-218597BB9A57}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.Debug|Win32.Build.0 = Debug|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.Release|Win32.ActiveCfg = Release|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.Release|Win32.Build.0 = Release|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {E8734A27-2205-460C-849C-5B8FC95E9EBC}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.Debug|Win32.Build.0 = Debug|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.Release|Win32.ActiveCfg = Release|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.Release|Win32.Build.0 = Release|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.Debug|Win32.Build.0 = Debug|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.Release|Win32.ActiveCfg = Release|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.Release|Win32.Build.0 = Release|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {B49E4038-0F40-494F-94D8-1CA30D8241A0}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.Debug|Win32.Build.0 = Debug|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.Release|Win32.ActiveCfg = Release|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.Release|Win32.Build.0 = Release|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {1B932C34-DE95-4A60-A50D-4EB702BC97AA}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.Debug|Win32.ActiveCfg = Debug|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.Debug|Win32.Build.0 = Debug|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.Release|Win32.ActiveCfg = Release|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.Release|Win32.Build.0 = Release|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {80A8E252-E760-4D8A-86E5-F32ECA1B8640}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.Debug|Win32.Build.0 = Debug|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.Release|Win32.ActiveCfg = Release|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.Release|Win32.Build.0 = Release|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.Debug|Win32.Build.0 = Debug|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.Release|Win32.ActiveCfg = Release|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.Release|Win32.Build.0 = Release|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {253F7FE0-0402-460C-8D9C-51A5E998A0B5}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.Debug|Win32.Build.0 = Debug|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.Release|Win32.ActiveCfg = Release|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.Release|Win32.Build.0 = Release|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {C019AD4E-D7BB-4EAB-B277-DB4FCD502383}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.Debug|Win32.ActiveCfg = Debug|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.Debug|Win32.Build.0 = Debug|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.Release|Win32.ActiveCfg = Release|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.Release|Win32.Build.0 = Release|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {54CA28AA-178A-411D-99DC-E6FD8F117C70}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.Debug|Win32.Build.0 = Debug|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.Release|Win32.ActiveCfg = Release|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.Release|Win32.Build.0 = Release|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.Debug|Win32.Build.0 = Debug|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.Release|Win32.ActiveCfg = Release|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.Release|Win32.Build.0 = Release|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {36ED9747-183D-4411-86AB-F0E6F775D3C0}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.Debug|Win32.Build.0 = Debug|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.Release|Win32.ActiveCfg = Release|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.Release|Win32.Build.0 = Release|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {F3356B1C-361D-48AD-9042-9B115EE536E3}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
{E12E04D0-C11C-36C0-950E-A203DCBFB37C}.Debug|Win32.ActiveCfg = Debug|Win32
{E12E04D0-C11C-36C0-950E-A203DCBFB37C}.MinSizeRel|Win32.ActiveCfg = Release|Win32
{E12E04D0-C11C-36C0-950E-A203DCBFB37C}.Release|Win32.ActiveCfg = Release|Win32
{E12E04D0-C11C-36C0-950E-A203DCBFB37C}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.Debug|Win32.ActiveCfg = Debug|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.Debug|Win32.Build.0 = Debug|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.Release|Win32.ActiveCfg = Release|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.Release|Win32.Build.0 = Release|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
- {C9E3DBF2-AA34-3900-9761-5A846CAB6397}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
diff --git a/build/qhull.vcproj b/build/qhull.vcproj
index 516e59b..a67874b 100644
--- a/build/qhull.vcproj
+++ b/build/qhull.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qhull"
- ProjectGUID="{0BDDB82D-3246-41E1-8691-9205CF705BFA}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{7AACF1DE-2A08-493F-9B09-218597BB9A57}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qhull.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhull.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_d.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_rd.lib "
OutputFile="..\bin\qhull.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qhull.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhull_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qhull.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhull.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\qhull.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qhull.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhull.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qhull.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhull.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\qhull.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qhull.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhull.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qhull.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qhull.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\qhull.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qhull.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qhull.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qhull.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\qhull\unix.c"
- >
+ RelativePath="..\src\qhull\unix_r.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/qhull_p.vcproj b/build/qhull_p.vcproj
new file mode 100644
index 0000000..f8a3faa
--- /dev/null
+++ b/build/qhull_p.vcproj
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="qhull_p"
+ ProjectGUID="{E8734A27-2205-460C-849C-5B8FC95E9EBC}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="qhull_p.dir\Debug"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer;qhull_p_EXPORTS"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_p.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer;qhull_p_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_p_d.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull\qhull_p-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_p.pdb"
+ GenerateDebugInformation="TRUE"
+ ImportLibrary="..\lib\qhull_p_d.lib"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="qhull_p.dir\Release"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_p_EXPORTS"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_p.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_p_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_p.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull\qhull_p-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_p.pdb"
+ ImportLibrary="..\lib\qhull_p.lib"/>
+ </Configuration>
+ <Configuration
+ Name="MinSizeRel|Win32"
+ OutputDirectory="MinSizeRel"
+ IntermediateDirectory="qhull_p.dir\MinSizeRel"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_p_EXPORTS"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_p.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_p_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_p.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull\qhull_p-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_p.pdb"
+ ImportLibrary="..\lib\qhull_p.lib"/>
+ </Configuration>
+ <Configuration
+ Name="RelWithDebInfo|Win32"
+ OutputDirectory="RelWithDebInfo"
+ IntermediateDirectory="qhull_p.dir\RelWithDebInfo"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_p_EXPORTS"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_p.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qhull_p_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_p.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull\qhull_p-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_p.pdb"
+ GenerateDebugInformation="TRUE"
+ ImportLibrary="..\lib\qhull_p.lib"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull\global.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\stat.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\geom2.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\poly2.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\merge.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\libqhull.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\geom.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\poly.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\qset.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\mem.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\random.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\usermem.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\userprintf.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\io.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\user.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\rboxlib.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\userprintf_rbox.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\qhull_p-exports.def">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull\libqhull.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\geom.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\io.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\mem.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\merge.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\poly.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\qhull_a.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\qset.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\random.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\stat.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\user.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/build/qhull_r.vcproj b/build/qhull_r.vcproj
new file mode 100644
index 0000000..919b513
--- /dev/null
+++ b/build/qhull_r.vcproj
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="qhull_r"
+ ProjectGUID="{D5D9D1F8-917B-4F5E-8522-DB9FC90874A3}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="qhull_r.dir\Debug"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qhull_r_EXPORTS"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qhull_r_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_rd.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull_r\qhull_r-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_rd.pdb"
+ GenerateDebugInformation="TRUE"
+ ImportLibrary="..\lib\qhull_rd.lib"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="qhull_r.dir\Release"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_r_EXPORTS"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_r_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_r.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull_r\qhull_r-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_r.pdb"
+ ImportLibrary="..\lib\qhull_r.lib"/>
+ </Configuration>
+ <Configuration
+ Name="MinSizeRel|Win32"
+ OutputDirectory="MinSizeRel"
+ IntermediateDirectory="qhull_r.dir\MinSizeRel"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_r_EXPORTS"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_r_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_r.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull_r\qhull_r-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_r.pdb"
+ ImportLibrary="..\lib\qhull_r.lib"/>
+ </Configuration>
+ <Configuration
+ Name="RelWithDebInfo|Win32"
+ OutputDirectory="RelWithDebInfo"
+ IntermediateDirectory="qhull_r.dir\RelWithDebInfo"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_r_EXPORTS"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhull_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qhull_r_EXPORTS"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\qhull_r.dll"
+ Version="7.0"
+ LinkIncremental="1"
+ ModuleDefinitionFile="..\src\libqhull_r\qhull_r-exports.def"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\qhull_r.pdb"
+ GenerateDebugInformation="TRUE"
+ ImportLibrary="..\lib\qhull_r.lib"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull_r\global_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\stat_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\geom2_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\poly2_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\merge_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\libqhull_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\geom_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\poly_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qset_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\mem_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\random_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\usermem_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\userprintf_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\io_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\user_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\rboxlib_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\userprintf_rbox_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qhull_r-exports.def">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull_r\libqhull_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\geom_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\io_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\mem_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\merge_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\poly_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qhull_ra.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qset_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\random_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\stat_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\user_r.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/build/qhullcpp.vcproj b/build/qhullcpp.vcproj
index 2d0f50e..b278be1 100644
--- a/build/qhullcpp.vcproj
+++ b/build/qhullcpp.vcproj
@@ -1,510 +1,365 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qhullcpp"
- ProjectGUID="{2C448FFE-CDF6-4639-BB23-39588F006C73}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{B49E4038-0F40-494F-94D8-1CA30D8241A0}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qhullcpp.dir\Debug"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="2"
+ DebugInformationFormat="3"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullcpp.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- ExceptionHandling="1"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullcpp_d.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="2"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullcpp_d.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullcpp_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qhullcpp.dir\Release"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="2"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullcpp.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="1"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullcpp.pdb"
- WarningLevel="3"
- CompileAs="2"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullcpp.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullcpp.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qhullcpp.dir\MinSizeRel"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="2"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullcpp.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="1"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullcpp.pdb"
- WarningLevel="3"
- CompileAs="2"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullcpp.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullcpp.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qhullcpp.dir\RelWithDebInfo"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="2"
+ DebugInformationFormat="3"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullcpp.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="1"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullcpp.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="2"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullcpp.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullcpp.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
- <File
- RelativePath="..\src\libqhullcpp\Coordinates.cpp"
- >
- </File>
+ Filter="">
<File
- RelativePath="..\src\libqhullcpp\PointCoordinates.cpp"
- >
+ RelativePath="..\src\libqhullcpp\Coordinates.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\Qhull.cpp"
- >
+ RelativePath="..\src\libqhullcpp\PointCoordinates.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullFacet.cpp"
- >
+ RelativePath="..\src\libqhullcpp\Qhull.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullFacetList.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullFacet.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullFacetSet.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullFacetList.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullHyperplane.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullFacetSet.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullPoint.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullHyperplane.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullPoints.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullPoint.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullPointSet.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullPointSet.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullQh.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullPoints.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullRidge.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullQh.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullSet.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullRidge.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullStat.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullSet.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullVertex.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullStat.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\QhullVertexSet.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullVertex.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\RboxPoints.cpp"
- >
+ RelativePath="..\src\libqhullcpp\QhullVertexSet.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\RoadError.cpp"
- >
+ RelativePath="..\src\libqhullcpp\RboxPoints.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\RoadLogEvent.cpp"
- >
+ RelativePath="..\src\libqhullcpp\RoadError.cpp">
</File>
<File
- RelativePath="..\src\libqhullcpp\UsingLibQhull.cpp"
- >
+ RelativePath="..\src\libqhullcpp\RoadLogEvent.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="">
<File
RelativePath="..\src\libqhullcpp\Coordinates.h">
</File>
<File
RelativePath="..\src\libqhullcpp\functionObjects.h">
</File>
<File
RelativePath="..\src\libqhullcpp\PointCoordinates.h">
</File>
<File
RelativePath="..\src\libqhullcpp\Qhull.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullError.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullFacet.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullFacetList.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullFacetSet.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullHyperplane.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullIterator.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullLinkedList.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullPoint.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullPoints.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullPointSet.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullQh.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullRidge.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullSet.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullSets.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullStat.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullVertex.h">
</File>
<File
RelativePath="..\src\libqhullcpp\QhullVertexSet.h">
</File>
<File
RelativePath="..\src\libqhullcpp\RboxPoints.h">
</File>
- <File
- RelativePath="..\src\libqhullcpp\UsingLibQhull.h">
- </File>
<File
RelativePath="..\src\libqhullcpp\RoadError.h">
</File>
<File
RelativePath="..\src\libqhullcpp\RoadLogEvent.h">
</File>
+ <File
+ RelativePath="..\src\qhulltest\RoadTest.h">
+ </File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/qhullstatic.vcproj b/build/qhullstatic.vcproj
index 6cbf374..394f957 100644
--- a/build/qhullstatic.vcproj
+++ b/build/qhullstatic.vcproj
@@ -1,419 +1,313 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qhullstatic"
- ProjectGUID="{3A95DE97-A2DE-4E8B-8E2D-F17652AEB947}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{1B932C34-DE95-4A60-A50D-4EB702BC97AA}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qhullstatic.dir\Debug"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic_d.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic_d.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullstatic_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qhullstatic.dir\Release"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullstatic.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qhullstatic.dir\MinSizeRel"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullstatic.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qhullstatic.dir\RelWithDebInfo"
ConfigurationType="4"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ OutputFile="..\lib\qhullstatic.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull\global.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\stat.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\geom2.c">
+ </File>
<File
- RelativePath="..\src\libqhull\geom.c"
- >
+ RelativePath="..\src\libqhull\poly2.c">
</File>
<File
- RelativePath="..\src\libqhull\geom2.c"
- >
+ RelativePath="..\src\libqhull\merge.c">
</File>
<File
- RelativePath="..\src\libqhull\global.c"
- >
+ RelativePath="..\src\libqhull\libqhull.c">
</File>
<File
- RelativePath="..\src\libqhull\io.c"
- >
+ RelativePath="..\src\libqhull\geom.c">
</File>
<File
- RelativePath="..\src\libqhull\libqhull.c"
- >
+ RelativePath="..\src\libqhull\poly.c">
</File>
<File
- RelativePath="..\src\libqhull\mem.c"
- >
+ RelativePath="..\src\libqhull\qset.c">
</File>
<File
- RelativePath="..\src\libqhull\merge.c"
- >
+ RelativePath="..\src\libqhull\mem.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\random.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\usermem.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\userprintf.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\io.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\user.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\rboxlib.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull\userprintf_rbox.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull\libqhull.h">
</File>
<File
- RelativePath="..\src\libqhull\poly.c"
- >
+ RelativePath="..\src\libqhull\geom.h">
</File>
<File
- RelativePath="..\src\libqhull\poly2.c"
- >
+ RelativePath="..\src\libqhull\io.h">
</File>
<File
- RelativePath="..\src\libqhull\qset.c"
- >
+ RelativePath="..\src\libqhull\mem.h">
</File>
<File
- RelativePath="..\src\libqhull\random.c"
- >
+ RelativePath="..\src\libqhull\merge.h">
</File>
<File
- RelativePath="..\src\libqhull\rboxlib.c"
- >
+ RelativePath="..\src\libqhull\poly.h">
</File>
<File
- RelativePath="..\src\libqhull\stat.c"
- >
+ RelativePath="..\src\libqhull\qhull_a.h">
</File>
<File
- RelativePath="..\src\libqhull\user.c"
- >
+ RelativePath="..\src\libqhull\qset.h">
</File>
<File
- RelativePath="..\src\libqhull\usermem.c"
- >
+ RelativePath="..\src\libqhull\random.h">
</File>
<File
- RelativePath="..\src\libqhull\userprintf.c"
- >
+ RelativePath="..\src\libqhull\stat.h">
</File>
<File
- RelativePath="..\src\libqhull\userprintf_rbox.c"
- >
+ RelativePath="..\src\libqhull\user.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/qhullstatic_p.vcproj b/build/qhullstatic_p.vcproj
deleted file mode 100644
index 22ddc2c..0000000
--- a/build/qhullstatic_p.vcproj
+++ /dev/null
@@ -1,415 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="qhullstatic_p"
- ProjectGUID="{4730C632-C24E-40E4-AF42-80F6C6226048}"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="qhullstatic_p.dir\Debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic_pd.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic_pd.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="qhullstatic_p.dir\Release"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic_p.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic_p.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="MinSizeRel|Win32"
- OutputDirectory="MinSizeRel"
- IntermediateDirectory="qhullstatic_p.dir\MinSizeRel"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic_p.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic_p.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="RelWithDebInfo|Win32"
- OutputDirectory="RelWithDebInfo"
- IntermediateDirectory="qhullstatic_p.dir\RelWithDebInfo"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- MkTypLibCompatible="false"
- TargetEnvironment="1"
- GenerateStublessProxies="true"
- TypeLibraryName="$(InputName).tlb"
- OutputDirectory="$(IntDir)"
- HeaderFileName="$(InputName).h"
- DLLDataFileName=""
- InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\lib\qhullstatic_p.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\lib\qhullstatic_p.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- >
- <File
- RelativePath="..\src\libqhull\geom.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\geom2.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\global.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\io.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\libqhull.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\mem.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\merge.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\poly.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\poly2.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\qset.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\random.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\rboxlib.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\stat.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\user.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\usermem.c"
- >
- </File>
- <File
- RelativePath="..\src\libqhull\userprintf.c"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/build/qhullstatic_r.vcproj b/build/qhullstatic_r.vcproj
new file mode 100644
index 0000000..fceb4ad
--- /dev/null
+++ b/build/qhullstatic_r.vcproj
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="qhullstatic_r"
+ ProjectGUID="{80A8E252-E760-4D8A-86E5-F32ECA1B8640}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="qhullstatic_r.dir\Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\qhullstatic_rd.lib"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="qhullstatic_r.dir\Release"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\qhullstatic_r.lib"/>
+ </Configuration>
+ <Configuration
+ Name="MinSizeRel|Win32"
+ OutputDirectory="MinSizeRel"
+ IntermediateDirectory="qhullstatic_r.dir\MinSizeRel"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\qhullstatic_r.lib"/>
+ </Configuration>
+ <Configuration
+ Name="RelWithDebInfo|Win32"
+ OutputDirectory="RelWithDebInfo"
+ IntermediateDirectory="qhullstatic_r.dir\RelWithDebInfo"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qhullstatic_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\qhullstatic_r.lib"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull_r\global_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\stat_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\geom2_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\poly2_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\merge_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\libqhull_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\geom_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\poly_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qset_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\mem_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\random_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\usermem_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\userprintf_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\io_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\user_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\rboxlib_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\userprintf_rbox_r.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull_r\libqhull_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\geom_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\io_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\mem_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\merge_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\poly_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qhull_ra.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qset_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\random_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\stat_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\user_r.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/build/qhulltest.vcproj b/build/qhulltest.vcproj
deleted file mode 100644
index c823cec..0000000
--- a/build/qhulltest.vcproj
+++ /dev/null
@@ -1,698 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="qhulltest"
- ProjectGUID="{E12E04D0-C11C-36C0-950E-A203DCBFB37C}"
- Keyword="Qt4VSv1.0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="."
- ATLMinimizesCRunTimeLibraryUsage="false"
- ConfigurationType="1"
- IntermediateDirectory="Debug\"
- UseOfMfc="0">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(QTDIR)\include\QtCore&quot;,&quot;$(QTDIR)\include\QtGui&quot;,&quot;$(QTDIR)\include&quot;,&quot;$(QTDIR)\include\QtTest&quot;,&quot;..\src\libqhullcpp&quot;,&quot;..\src&quot;,&quot;..\src&quot;,&quot;$(QTDIR)\include\ActiveQt&quot;,&quot;moc&quot;,&quot;..\src\qhulltest&quot;,&quot;.&quot;,$(QTDIR)\mkspecs\win32-msvc2005"
- AdditionalOptions="-Zm200 -w34100 -w34189"
- AssemblerListingLocation="Debug\"
- BufferSecurityCheck="false"
- DebugInformationFormat="3"
- ExceptionHandling="1"
- ForcedIncludeFiles="..\src\qhulltest\RoadTest.h"
- GeneratePreprocessedFile="0"
- ObjectFile="Debug\"
- Optimization ="4"
- PrecompiledHeaderFile="$(IntDir)\qhulltest.pch"
- PrecompiledHeaderThrough="..\src\qhulltest\RoadTest.h"
- PreprocessorDefinitions="UNICODE,WIN32,QT_LARGEFILE_SUPPORT,qh_QHpointer,QT_DLL,QT_GUI_LIB,QT_CORE_LIB,QT_HAVE_MMX,QT_HAVE_3DNOW,QT_HAVE_SSE,QT_HAVE_MMXEXT,QT_HAVE_SSE2,QT_THREAD_SUPPORT,QT_NO_DYNAMIC_CAST"
- ProgramDataBaseFileName=".\"
- RuntimeTypeInfo="false" RuntimeLibrary="3"
- SuppressStartupBanner="true"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="2"
- WarningLevel="3" />
- <Tool
- Name="VCCustomBuildTool" />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="qhullcpp_d.lib qhullstatic_pd.lib $(QTDIR)\lib\QtTestd4.lib $(QTDIR)\lib\QtGuid4.lib $(QTDIR)\lib\QtCored4.lib"
- AdditionalLibraryDirectories="$(QTDIR)\lib,../lib"
- GenerateDebugInformation="true"
- IgnoreImportLibrary="true"
- LinkIncremental="1"
- LinkTimeCodeGeneration="0"
- OutputFile="..\bin\qhulltest.exe"
- ProgramDatabaseFile=""
- SubSystem="1"
- SuppressStartupBanner="true" />
- <Tool
- Name="VCMIDLTool"
- DefaultCharType="0"
- EnableErrorChecks="1"
- WarningLevel="0" />
- <Tool
- Name="VCPostBuildEventTool" />
- <Tool
- Name="VCPreBuildEventTool" />
- <Tool
- Name="VCPreLinkEventTool" />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="UNICODE,WIN32,QT_LARGEFILE_SUPPORT,qh_QHpointer,QT_DLL,QT_GUI_LIB,QT_CORE_LIB,QT_HAVE_MMX,QT_HAVE_3DNOW,QT_HAVE_SSE,QT_HAVE_MMXEXT,QT_HAVE_SSE2,QT_THREAD_SUPPORT,QT_NO_DYNAMIC_CAST,_DEBUG" />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="."
- ATLMinimizesCRunTimeLibraryUsage="false"
- ConfigurationType="1"
- IntermediateDirectory="Release\"
- UseOfMfc="0">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(QTDIR)\include\QtCore&quot;,&quot;$(QTDIR)\include\QtGui&quot;,&quot;$(QTDIR)\include&quot;,&quot;$(QTDIR)\include\QtTest&quot;,&quot;..\src\libqhullcpp&quot;,&quot;..\src&quot;,&quot;..\src&quot;,&quot;$(QTDIR)\include\ActiveQt&quot;,&quot;moc&quot;,&quot;..\src\qhulltest&quot;,&quot;.&quot;,$(QTDIR)\mkspecs\win32-msvc2005"
- AdditionalOptions="-Zm200 -w34100 -w34189"
- AssemblerListingLocation="Release\"
- BufferSecurityCheck="false"
- DebugInformationFormat="0"
- ExceptionHandling="1"
- ForcedIncludeFiles="..\src\qhulltest\RoadTest.h"
- GeneratePreprocessedFile="0"
- ObjectFile="Release\"
- Optimization ="2"
- PrecompiledHeaderFile="$(IntDir)\qhulltest.pch"
- PrecompiledHeaderThrough="..\src\qhulltest\RoadTest.h"
- PreprocessorDefinitions="QT_NO_DEBUG,NDEBUG,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,qh_QHpointer,QT_DLL,QT_NO_DEBUG,QT_GUI_LIB,QT_CORE_LIB,QT_HAVE_MMX,QT_HAVE_3DNOW,QT_HAVE_SSE,QT_HAVE_MMXEXT,QT_HAVE_SSE2,QT_THREAD_SUPPORT,QT_NO_DYNAMIC_CAST,NDEBUG"
- ProgramDataBaseFileName=".\"
- RuntimeTypeInfo="false" RuntimeLibrary="2"
- SuppressStartupBanner="true"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="2"
- WarningLevel="3" />
- <Tool
- Name="VCCustomBuildTool" />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="../lib\qhullcpp.lib ../lib\qhullstatic_p.lib $(QTDIR)\lib\QtTest4.lib $(QTDIR)\lib\QtGui4.lib $(QTDIR)\lib\QtCore4.lib"
- AdditionalLibraryDirectories="$(QTDIR)\lib,../lib"
- GenerateDebugInformation="false"
- IgnoreImportLibrary="true"
- LinkIncremental="1"
- LinkTimeCodeGeneration="0"
- OutputFile="..\bin\qhulltest.exe"
- ProgramDatabaseFile=""
- SubSystem="1"
- SuppressStartupBanner="true" />
- <Tool
- Name="VCMIDLTool"
- DefaultCharType="0"
- EnableErrorChecks="1"
- WarningLevel="0" />
- <Tool
- Name="VCPostBuildEventTool" />
- <Tool
- Name="VCPreBuildEventTool" />
- <Tool
- Name="VCPreLinkEventTool" />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="QT_NO_DEBUG,NDEBUG,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,qh_QHpointer,QT_DLL,QT_NO_DEBUG,QT_GUI_LIB,QT_CORE_LIB,QT_HAVE_MMX,QT_HAVE_3DNOW,QT_HAVE_SSE,QT_HAVE_MMXEXT,QT_HAVE_SSE2,QT_THREAD_SUPPORT,QT_NO_DYNAMIC_CAST" />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\qhulltest\Coordinates_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\PointCoordinates_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\Qhull_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullFacet_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullFacetList_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullFacetSet_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullHyperplane_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullLinkedList_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullPoint_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullPoints_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullPointSet_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullRidge_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullSet_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\qhulltest.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\QhullVertex_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\libqhullcpp\qt-qhull.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\RboxPoints_test.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\RoadTest.cpp"
- >
- </File>
- <File
- RelativePath="..\src\qhulltest\UsingLibQhull_test.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\src\qhulltest\RoadTest.h"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating precompiled header source file &apos;..\src\qhulltest\RoadTest.h.cpp&apos; ..."
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\RoadTest.h -o moc\moc_RoadTest.cpp &amp;&amp; echo /*-------------------------------------------------------------------- &gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * Precompiled header source file used by Visual Studio.NET to generate&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * the .pch file.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo *&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * Due to issues with the dependencies checker within the IDE, it&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * sometimes fails to recompile the PCH file, if we force the IDE to&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * create the PCH file directly from the header file.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo *&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * This file is auto-generated by qmake since no PRECOMPILED_SOURCE was&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * specified, and is used as the common stdafx.cpp. The file is only&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * generated when creating .vcproj project files, and is not used for&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * command line compilations by nmake.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo *&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * WARNING: All changes made in this file will be lost.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo --------------------------------------------------------------------*/&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo #include &quot;RoadTest.h&quot;&gt;&gt;..\src\qhulltest\RoadTest.h.cpp&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\RoadTest.h;$(QTDIR)\bin\moc.exe"
- Outputs="moc\moc_RoadTest.cpp;..\src\qhulltest\RoadTest.h.cpp"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating precompiled header source file &apos;..\src\qhulltest\RoadTest.h.cpp&apos; ..."
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\RoadTest.h -o moc\moc_RoadTest.cpp &amp;&amp; echo /*-------------------------------------------------------------------- &gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * Precompiled header source file used by Visual Studio.NET to generate&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * the .pch file.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo *&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * Due to issues with the dependencies checker within the IDE, it&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * sometimes fails to recompile the PCH file, if we force the IDE to&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * create the PCH file directly from the header file.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo *&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * This file is auto-generated by qmake since no PRECOMPILED_SOURCE was&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * specified, and is used as the common stdafx.cpp. The file is only&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * generated when creating .vcproj project files, and is not used for&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * command line compilations by nmake.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo *&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo * WARNING: All changes made in this file will be lost.&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo --------------------------------------------------------------------*/&gt;&gt;..\src\qhulltest\RoadTest.h.cpp &amp;&amp; echo #include &quot;RoadTest.h&quot;&gt;&gt;..\src\qhulltest\RoadTest.h.cpp&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\RoadTest.h;$(QTDIR)\bin\moc.exe"
- Outputs="moc\moc_RoadTest.cpp;..\src\qhulltest\RoadTest.h.cpp"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Generated Files"
- Filter="cpp;c;cxx;moc;h;def;odl;idl;res;"
- UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
- >
- <File
- RelativePath="moc\Coordinates_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\Coordinates_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\Coordinates_test.cpp -o moc\Coordinates_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\Coordinates_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\Coordinates_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\Coordinates_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\Coordinates_test.cpp -o moc\Coordinates_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\Coordinates_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\Coordinates_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\PointCoordinates_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\PointCoordinates_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\PointCoordinates_test.cpp -o moc\PointCoordinates_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\PointCoordinates_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\PointCoordinates_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\PointCoordinates_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\PointCoordinates_test.cpp -o moc\PointCoordinates_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\PointCoordinates_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\PointCoordinates_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\Qhull_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\Qhull_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\Qhull_test.cpp -o moc\Qhull_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\Qhull_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\Qhull_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\Qhull_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\Qhull_test.cpp -o moc\Qhull_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\Qhull_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\Qhull_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullFacet_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullFacet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullFacet_test.cpp -o moc\QhullFacet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullFacet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullFacet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullFacet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullFacet_test.cpp -o moc\QhullFacet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullFacet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullFacet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullFacetList_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullFacetList_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullFacetList_test.cpp -o moc\QhullFacetList_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullFacetList_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullFacetList_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullFacetList_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullFacetList_test.cpp -o moc\QhullFacetList_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullFacetList_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullFacetList_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullFacetSet_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullFacetSet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullFacetSet_test.cpp -o moc\QhullFacetSet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullFacetSet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullFacetSet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullFacetSet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullFacetSet_test.cpp -o moc\QhullFacetSet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullFacetSet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullFacetSet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullHyperplane_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullHyperplane_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullHyperplane_test.cpp -o moc\QhullHyperplane_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullHyperplane_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullHyperplane_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullHyperplane_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullHyperplane_test.cpp -o moc\QhullHyperplane_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullHyperplane_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullHyperplane_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullLinkedList_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullLinkedList_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullLinkedList_test.cpp -o moc\QhullLinkedList_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullLinkedList_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullLinkedList_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullLinkedList_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullLinkedList_test.cpp -o moc\QhullLinkedList_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullLinkedList_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullLinkedList_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullPoint_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullPoint_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullPoint_test.cpp -o moc\QhullPoint_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullPoint_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullPoint_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullPoint_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullPoint_test.cpp -o moc\QhullPoint_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullPoint_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullPoint_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullPoints_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullPoints_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullPoints_test.cpp -o moc\QhullPoints_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullPoints_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullPoints_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullPoints_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullPoints_test.cpp -o moc\QhullPoints_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullPoints_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullPoints_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullPointSet_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullPointSet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullPointSet_test.cpp -o moc\QhullPointSet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullPointSet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullPointSet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullPointSet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullPointSet_test.cpp -o moc\QhullPointSet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullPointSet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullPointSet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullRidge_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullRidge_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullRidge_test.cpp -o moc\QhullRidge_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullRidge_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullRidge_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullRidge_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullRidge_test.cpp -o moc\QhullRidge_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullRidge_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullRidge_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullSet_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullSet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullSet_test.cpp -o moc\QhullSet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullSet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullSet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullSet_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullSet_test.cpp -o moc\QhullSet_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullSet_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullSet_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\QhullVertex_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullVertex_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullVertex_test.cpp -o moc\QhullVertex_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullVertex_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullVertex_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\QhullVertex_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\QhullVertex_test.cpp -o moc\QhullVertex_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\QhullVertex_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\QhullVertex_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\RboxPoints_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\RboxPoints_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\RboxPoints_test.cpp -o moc\RboxPoints_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\RboxPoints_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\RboxPoints_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\RboxPoints_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\RboxPoints_test.cpp -o moc\RboxPoints_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\RboxPoints_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\RboxPoints_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\qhulltest\RoadTest.h.cpp"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"
- PrecompiledHeaderThrough="$(INHERIT)"
- ForcedIncludeFiles="$(NOINHERIT)"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"
- PrecompiledHeaderThrough="$(INHERIT)"
- ForcedIncludeFiles="$(NOINHERIT)"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="moc\UsingLibQhull_test.moc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\UsingLibQhull_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\UsingLibQhull_test.cpp -o moc\UsingLibQhull_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\UsingLibQhull_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\UsingLibQhull_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="MOC ..\src\qhulltest\UsingLibQhull_test.cpp"
- CommandLine="$(QTDIR)\bin\moc.exe -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -Dqh_QHpointer -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NO_DYNAMIC_CAST -I&quot;$(QTDIR)\include\QtCore&quot; -I&quot;$(QTDIR)\include\QtGui&quot; -I&quot;$(QTDIR)\include&quot; -I&quot;$(QTDIR)\include\QtTest&quot; -I&quot;..\src\libqhullcpp&quot; -I&quot;..\src&quot; -I&quot;..\src&quot; -I&quot;$(QTDIR)\include\ActiveQt&quot; -I&quot;moc&quot; -I&quot;..\src\qhulltest&quot; -I&quot;.&quot; -I$(QTDIR)\mkspecs\win32-msvc2005 -D_MSC_VER=1400 -DWIN32 ..\src\qhulltest\UsingLibQhull_test.cpp -o moc\UsingLibQhull_test.moc&#x0D;&#x0A;"
- AdditionalDependencies="..\src\qhulltest\UsingLibQhull_test.cpp;$(QTDIR)\bin\moc.exe"
- Outputs="moc\UsingLibQhull_test.moc"
- Path="$(QTDIR)\bin" />
- </FileConfiguration>
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/build/qvoronoi.vcproj b/build/qvoronoi.vcproj
index 74a748a..7f73867 100644
--- a/build/qvoronoi.vcproj
+++ b/build/qvoronoi.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qvoronoi"
- ProjectGUID="{52135D45-9834-475A-9E4D-12852711A714}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{71B25045-5B56-4D69-B8DA-1F16D3D8B6E5}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="qvoronoi.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_d.lib "
OutputFile="..\bin\qvoronoi.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qvoronoi.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qvoronoi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qvoronoi_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="qvoronoi.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qvoronoi.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qvoronoi.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qvoronoi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qvoronoi.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="qvoronoi.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qvoronoi.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\qvoronoi.pdb"
SubSystem="1"
- ImportLibrary="..\lib\qvoronoi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qvoronoi.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="qvoronoi.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\qvoronoi.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\qvoronoi.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\qvoronoi.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\qvoronoi.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\qvoronoi.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\qvoronoi\qvoronoi.c"
- >
+ RelativePath="..\src\qvoronoi\qvoronoi.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/rbox.vcproj b/build/rbox.vcproj
index b7e1e4f..0c1b946 100644
--- a/build/rbox.vcproj
+++ b/build/rbox.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="rbox"
- ProjectGUID="{887E64E6-D850-4B31-8E06-66E5B7E92F6D}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{253F7FE0-0402-460C-8D9C-51A5E998A0B5}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="rbox.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\rbox.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\rbox.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_d.lib "
OutputFile="..\bin\rbox.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\rbox.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\rbox.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\rbox_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="rbox.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\rbox.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\rbox.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\rbox.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\rbox.pdb"
SubSystem="1"
- ImportLibrary="..\lib\rbox.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\rbox.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="rbox.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\rbox.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\rbox.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\rbox.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\rbox.pdb"
SubSystem="1"
- ImportLibrary="..\lib\rbox.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\rbox.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="rbox.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\rbox.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\rbox.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic.lib "
OutputFile="..\bin\rbox.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\rbox.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\rbox.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\rbox.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\rbox\rbox.c"
- >
+ RelativePath="..\src\rbox\rbox.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/testqset.vcproj b/build/testqset.vcproj
index a1ecd95..6bc9f1b 100644
--- a/build/testqset.vcproj
+++ b/build/testqset.vcproj
@@ -1,433 +1,282 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="testqset"
- ProjectGUID="{C9E3DBF2-AA34-3900-9761-5A846CAB6397}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{C019AD4E-D7BB-4EAB-B277-DB4FCD502383}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="testqset.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\testqset.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\testqset.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\testqset.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\testqset_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="testqset.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\testqset.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\testqset.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\testqset.pdb"
SubSystem="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\testqset.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="testqset.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\testqset.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\testqset.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\testqset.pdb"
SubSystem="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\testqset.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="testqset.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\testqset.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
OutputFile="..\bin\testqset.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\testqset.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\testqset.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull\qset.c">
+ </File>
<File
- RelativePath="..\src\libqhull\mem.c"
- >
+ RelativePath="..\src\libqhull\mem.c">
</File>
<File
- RelativePath="..\src\libqhull\qset.c"
- >
+ RelativePath="..\src\testqset\testqset.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull\mem.h">
</File>
<File
- RelativePath="..\src\testqset\testqset.c"
- >
+ RelativePath="..\src\libqhull\qset.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/testqset_r.vcproj b/build/testqset_r.vcproj
new file mode 100644
index 0000000..d409214
--- /dev/null
+++ b/build/testqset_r.vcproj
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="testqset_r"
+ ProjectGUID="{54CA28AA-178A-411D-99DC-E6FD8F117C70}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="testqset_r.dir\Debug"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\testqset_r.exe"
+ Version="0.0"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\testqset_rd.pdb"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ ImportLibrary="..\lib\testqset_rd.lib"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="testqset_r.dir\Release"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\testqset_r.exe"
+ Version="0.0"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\testqset_r.pdb"
+ SubSystem="1"
+ ImportLibrary="..\lib\testqset_r.lib"/>
+ </Configuration>
+ <Configuration
+ Name="MinSizeRel|Win32"
+ OutputDirectory="MinSizeRel"
+ IntermediateDirectory="testqset_r.dir\MinSizeRel"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\testqset_r.exe"
+ Version="0.0"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\testqset_r.pdb"
+ SubSystem="1"
+ ImportLibrary="..\lib\testqset_r.lib"/>
+ </Configuration>
+ <Configuration
+ Name="RelWithDebInfo|Win32"
+ OutputDirectory="RelWithDebInfo"
+ IntermediateDirectory="testqset_r.dir\RelWithDebInfo"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\testqset_r.pdb"
+/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
+ <Tool
+ Name="VCMIDLTool"
+ MkTypLibCompatible="FALSE"
+ TargetEnvironment="1"
+ GenerateStublessProxies="TRUE"
+ TypeLibraryName="$(InputName).tlb"
+ OutputDirectory="$(IntDir)"
+ HeaderFileName="$(InputName).h"
+ DLLDataFileName=""
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib "
+ OutputFile="..\bin\testqset_r.exe"
+ Version="0.0"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""
+ ProgramDatabaseFile="..\bin\testqset_r.pdb"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ ImportLibrary="..\lib\testqset_r.lib"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull_r\qset_r.c">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\mem_r.c">
+ </File>
+ <File
+ RelativePath="..\src\testqset_r\testqset_r.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\src\libqhull_r\mem_r.h">
+ </File>
+ <File
+ RelativePath="..\src\libqhull_r\qset_r.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/build/user_eg.vcproj b/build/user_eg.vcproj
index b32a175..6bd53c6 100644
--- a/build/user_eg.vcproj
+++ b/build/user_eg.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="user_eg"
- ProjectGUID="{ACC05378-EF76-436F-A33D-F0A1AB916326}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{D7F52ABC-F2AA-4F9C-9717-C56409B3AE60}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="user_eg.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_dllimport"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_dllimport"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer;qh_QHpointer_dllimport"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_pd.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_rd.lib "
OutputFile="..\bin\user_eg.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\user_eg.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\user_eg.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="user_eg.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qh_QHpointer_dllimport"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_p.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_r.lib "
OutputFile="..\bin\user_eg.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\user_eg.pdb"
SubSystem="1"
- ImportLibrary="..\lib\user_eg.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="user_eg.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qh_QHpointer_dllimport"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_p.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_r.lib "
OutputFile="..\bin\user_eg.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\user_eg.pdb"
SubSystem="1"
- ImportLibrary="..\lib\user_eg.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="user_eg.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer;qh_QHpointer_dllimport"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_p.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_r.lib "
OutputFile="..\bin\user_eg.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\user_eg.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\user_eg.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\user_eg\user_eg.c"
- >
+ RelativePath="..\src\user_eg\user_eg_r.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/user_eg2.vcproj b/build/user_eg2.vcproj
index 1ff6ef6..5afc7ee 100644
--- a/build/user_eg2.vcproj
+++ b/build/user_eg2.vcproj
@@ -1,429 +1,266 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="user_eg2"
- ProjectGUID="{84EB3982-1012-49E9-975E-BFD2F0D312C2}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{36ED9747-183D-4411-86AB-F0E6F775D3C0}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="user_eg2.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg2.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_dllimport"
- ExceptionHandling="0"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg2.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_dllimport"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull_d.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_rd.lib "
OutputFile="..\bin\user_eg2.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\user_eg2.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\user_eg2.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg2_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="user_eg2.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg2.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg2.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\user_eg2.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\user_eg2.pdb"
SubSystem="1"
- ImportLibrary="..\lib\user_eg2.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg2.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="user_eg2.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg2.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg2.pdb"
- WarningLevel="3"
- CompileAs="1"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\user_eg2.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\user_eg2.pdb"
SubSystem="1"
- ImportLibrary="..\lib\user_eg2.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg2.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="user_eg2.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="1"
+ DebugInformationFormat="3"
+ ExceptionHandling="0"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg2.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
- ExceptionHandling="0"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg2.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="1"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_dllimport"
- AdditionalIncludeDirectories="..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhull.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\user_eg2.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\user_eg2.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\user_eg2.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg2.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\user_eg2\user_eg2.c"
- >
+ RelativePath="..\src\user_eg2\user_eg2_r.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/build/user_eg3.vcproj b/build/user_eg3.vcproj
index bf8ccf3..7cdf5dd 100644
--- a/build/user_eg3.vcproj
+++ b/build/user_eg3.vcproj
@@ -1,429 +1,270 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="user_eg3"
- ProjectGUID="{7668C45C-60AA-457C-BA91-4F94AAB6A540}"
- Keyword="Win32Proj"
- >
+ ProjectGUID="{F3356B1C-361D-48AD-9042-9B115EE536E3}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
- Name="Win32"
- />
+ Name="Win32"/>
</Platforms>
- <ToolFiles>
- </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="user_eg3.dir\Debug"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ BasicRuntimeChecks="3"
+ CompileAs="2"
+ DebugInformationFormat="3"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="0"
+ Optimization="0"
+ RuntimeTypeInfo="false" RuntimeLibrary="3"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ AssemblerListingLocation="Debug"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg3.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="0"
- InlineFunctionExpansion="0"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- ExceptionHandling="1"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Debug"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg3.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="2"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp_d.lib ..\lib\qhullstatic_pd.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp_d.lib ..\lib\qhullstatic_rd.lib "
OutputFile="..\bin\user_eg3.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\user_eg3.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\user_eg3.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg3_d.lib"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="user_eg3.dir\Release"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="2"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="2"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="Release"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg3.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="2"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="1"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="Release"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg3.pdb"
- WarningLevel="3"
- CompileAs="2"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp.lib ..\lib\qhullstatic_p.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\user_eg3.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\user_eg3.pdb"
SubSystem="1"
- ImportLibrary="..\lib\user_eg3.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg3.lib"/>
</Configuration>
<Configuration
Name="MinSizeRel|Win32"
OutputDirectory="MinSizeRel"
IntermediateDirectory="user_eg3.dir\MinSizeRel"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="2"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="1"
+ Optimization="1"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="MinSizeRel"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg3.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="1"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="1"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="MinSizeRel"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg3.pdb"
- WarningLevel="3"
- CompileAs="2"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp.lib ..\lib\qhullstatic_p.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\user_eg3.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ProgramDatabaseFile="..\bin\user_eg3.pdb"
SubSystem="1"
- ImportLibrary="..\lib\user_eg3.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg3.lib"/>
</Configuration>
<Configuration
Name="RelWithDebInfo|Win32"
OutputDirectory="RelWithDebInfo"
IntermediateDirectory="user_eg3.dir\RelWithDebInfo"
ConfigurationType="1"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
<Tool
- Name="VCCustomBuildTool"
- />
+ Name="VCCLCompilerTool"
+ AdditionalOptions=" /Zm1000"
+ AdditionalIncludeDirectories="..\src;"
+ CompileAs="2"
+ DebugInformationFormat="3"
+ ExceptionHandling="1"
+ InlineFunctionExpansion="1"
+ Optimization="2"
+ RuntimeTypeInfo="false" RuntimeLibrary="2"
+
+ WarningLevel="3"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ AssemblerListingLocation="RelWithDebInfo"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="..\bin\user_eg3.pdb"
+/>
<Tool
- Name="VCXMLDataGeneratorTool"
- />
+ Name="VCCustomBuildTool"/>
<Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="..\src;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"/>
<Tool
Name="VCMIDLTool"
- MkTypLibCompatible="false"
+ MkTypLibCompatible="FALSE"
TargetEnvironment="1"
- GenerateStublessProxies="true"
+ GenerateStublessProxies="TRUE"
TypeLibraryName="$(InputName).tlb"
OutputDirectory="$(IntDir)"
HeaderFileName="$(InputName).h"
DLLDataFileName=""
InterfaceIdentifierFileName="$(InputName)_i.c"
- ProxyFileName="$(InputName)_p.c"
- />
+ ProxyFileName="$(InputName)_p.c"/>
<Tool
- Name="VCCLCompilerTool"
- AdditionalOptions=" /Zm1000"
- Optimization="2"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- ExceptionHandling="1"
- RuntimeLibrary="2"
- RuntimeTypeInfo="false"
- AssemblerListingLocation="RelWithDebInfo"
- ObjectFile="$(IntDir)\"
- ProgramDataBaseFileName="..\bin\user_eg3.pdb"
- WarningLevel="3"
- DebugInformationFormat="3"
- CompileAs="2"
- />
+ Name="VCPreBuildEventTool"/>
<Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;qh_QHpointer"
- AdditionalIncludeDirectories="..\src\libqhullcpp;..\src;..\src\libqhull;"
- />
+ Name="VCPreLinkEventTool"/>
<Tool
- Name="VCPreLinkEventTool"
- />
+ Name="VCPostBuildEventTool"/>
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalOptions=" /STACK:10000000 /machine:X86 /debug"
- AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp.lib ..\lib\qhullstatic_p.lib "
+ AdditionalDependencies="$(NOINHERIT) kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ..\lib\qhullcpp.lib ..\lib\qhullstatic_r.lib "
OutputFile="..\bin\user_eg3.exe"
- Version="6.0"
+ Version="0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\user_eg3.pdb"
+ GenerateDebugInformation="TRUE"
SubSystem="1"
- ImportLibrary="..\lib\user_eg3.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
+ ImportLibrary="..\lib\user_eg3.lib"/>
</Configuration>
</Configurations>
- <References>
- </References>
<Files>
<Filter
Name="Source Files"
- >
+ Filter="">
<File
- RelativePath="..\src\user_eg3\user_eg3.cpp"
- >
+ RelativePath="..\src\user_eg3\user_eg3_r.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
diff --git a/config/Makefile-am-eg b/config/Makefile-am-eg
deleted file mode 100644
index 539f26f..0000000
--- a/config/Makefile-am-eg
+++ /dev/null
@@ -1,25 +0,0 @@
-### Makefile.am for the qhull package (eg)
-### Author: Rafael Laboissiere <rafael@debian.org>
-### Created: Mon Dec 3 21:36:21 CET 2001
-### Update for 2010.1: O. Lahaye, jun'10
-### Draft update for 2011.2: B. Barber, dec'11
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-examplesdir = $(docdir)/examples
-
-# which:
-examples_DATA = \
- q_eg \
- q_egtest \
- q_test \
- q_test-ok.txt \
- q_test.bat \
- Qhull-go.bat \
- qhulltest-ok.txt
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = $(examples_DATA)
diff --git a/config/Makefile-am-html b/config/Makefile-am-html
deleted file mode 100644
index 12cc449..0000000
--- a/config/Makefile-am-html
+++ /dev/null
@@ -1,60 +0,0 @@
-### Makefile.am for the qhull package (html)
-### Author: Rafael Laboissiere <rafael@debian.org>
-### Created: Mon Dec 3 21:36:21 CET 2001
-### Update for 2010.1: O. Lahaye, jun'10
-### Draft update for 2011.2: B. Barber, dec'11
-
-### Man pages (trick to get around .man extension)
-
-%.1: %.man
- cp $< $@
-CLEANFILES = *.1
-man_MANS = rbox.1 qhull.1
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-htmldir = $(docdir)/html
-
-# which:
-html_DATA = \
- index.htm \
- normal_voronoi_knauss_oesterle.jpg \
- qconvex.htm \
- qdelau_f.htm \
- qdelaun.htm \
- qhalf.htm \
- qhull.htm \
- qvoron_f.htm \
- qvoronoi.htm \
- rbox.htm \
- qh--4d.gif \
- qh--cone.gif \
- qh--dt.gif \
- qh--geom.gif \
- qh--half.gif \
- qh--rand.gif \
- qh-code.htm \
- qh-eg.htm \
- qh-faq.htm \
- qh-get.htm \
- qh-impre.htm \
- qh-optc.htm \
- qh-optf.htm \
- qh-optg.htm \
- qh-opto.htm \
- qh-optp.htm \
- qh-optq.htm \
- qh-optt.htm \
- qh-quick.htm
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
- $(html_DATA) \
- qhull.man \
- qhull.txt \
- qhull-cpp.xml\
- rbox.man \
- rbox.txt
diff --git a/config/Makefile-am-libqhull b/config/Makefile-am-libqhull
deleted file mode 100644
index 86f73e4..0000000
--- a/config/Makefile-am-libqhull
+++ /dev/null
@@ -1,103 +0,0 @@
-### Makefile.am for the qhull package (src)
-### Author: Rafael Laboissiere <rafael@debian.org>
-### Created: Mon Dec 3 21:36:21 CET 2001
-
-### Shared Library
-
-# to:
-lib_LTLIBRARIES = libqhull.la
-
-# from:
-libqhull_la_SOURCES = \
- rboxlib.c \
- user.c \
- global.c \
- stat.c \
- io.c \
- geom2.c \
- poly2.c \
- merge.c \
- libqhull.c \
- geom.c \
- poly.c \
- qset.c \
- mem.c \
- usermem.c \
- userprintf.c \
- userprintf_rbox.c \
- random.c
-
-# how:
-libqhull_la_LDFLAGS = -version-info 6:3:1 -lm
-
-### Utility programs
-
-# to:
-bin_PROGRAMS = qhull rbox qconvex qdelaunay qvoronoi qhalf testqset
-
-# from:
-qhull_SOURCES = unix.c
-rbox_SOURCES = rbox.c
-qconvex_SOURCES = qconvex.c
-qdelaunay_SOURCES = qdelaun.c
-qvoronoi_SOURCES = qvoronoi.c
-qhalf_SOURCES = qhalf.c
-testqset_SOURCES = testqset.c qset.c mem.c
-
-# how:
-qhull_LDADD = libqhull.la
-rbox_LDADD = libqhull.la
-qconvex_LDADD = libqhull.la
-qdelaunay_LDADD = libqhull.la
-qvoronoi_LDADD = libqhull.la
-qhalf_LDADD = libqhull.la
-
-### Include files
-
-pkginclude_HEADERS = \
- geom.h \
- mem.h \
- poly.h \
- qhull_a.h \
- stat.h \
- io.h \
- merge.h \
- libqhull.h \
- random.h \
- qset.h \
- user.h
-
-
-### Example programs
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-examplesdir = $(docdir)/examples
-
-# which:
-examples_DATA = \
- user_eg.c \
- user_eg2.c \
- Makefile \
- Mborland
-
-doc_DATA = \
- Changes.txt \
- index.htm \
- qh-geom.htm \
- qh-globa.htm \
- qh-io.htm \
- qh-mem.htm \
- qh-merge.htm \
- qh-poly.htm \
- qh-qhull.htm \
- qh-set.htm \
- qh-stat.htm \
- qh-user.htm
-
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
- $(doc_DATA) \
- $(examples_DATA)
diff --git a/config/Makefile-am-main b/config/Makefile-am-main
deleted file mode 100644
index 8ad265a..0000000
--- a/config/Makefile-am-main
+++ /dev/null
@@ -1,29 +0,0 @@
-### Makefile.am for the qhull package (main)
-### Author: Rafael Laboissiere <rafael@debian.org>
-### Created: Mon Dec 3 21:36:21 CET 2001
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-
-# which:
-doc_DATA = \
- index.htm \
- Announce.txt \
- COPYING.txt \
- README.txt \
- REGISTER.txt
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
- $(doc_DATA) \
- .gitignore \
- CMakeLists.txt \
- File_id.diz \
- QHULL-GO.lnk
-
-### Subdirectories for Automaking
-
-SUBDIRS = src/libqhull html eg config
diff --git a/config/Makefile.am b/config/Makefile.am
deleted file mode 100644
index f4792ca..0000000
--- a/config/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-### Makefile.am for the qhull package (config)
-### Author: Rafael Laboissiere <rafael@debian.org>
-### Created: Mon Dec 3 21:36:21 CET 2001
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
- README \
- bootstrap.sh \
- Makefile-am-main \
- Makefile-am-eg \
- Makefile-am-html \
- Makefile-am-src
-
diff --git a/config/README b/config/README
deleted file mode 100644
index 758fe71..0000000
--- a/config/README
+++ /dev/null
@@ -1,30 +0,0 @@
-Autotools configuration for Qhull
----------------------------------
-
-This directory contains all the files needed to bootstrap the Qhull package
-for using Autoconf, Automake, and Libtool.
-
-See ../README.txt for instructions on building with make, cmake, qt, and Microsoft DevStudio
-
-WARNING -- Reworked for qhull-2012.1 but not tested.
- Produces qhull.so
- Ignores the C++ interface and libqhull_p.so
- The patch subdirectory is out-of-date.
- It was not used for Qhull 2009.1
- user.h sets qh_QHpointer=0 (static allocation of qh_qh)
- Brad Barber <bradb@shore.net>, 2012-01-27
-
-Go to the top source dir and type:
-
- config/bootstrap.sh
-
-And then the usual:
-
- ./configure --prefix=/your/preferred/path/here
- make
- make install
-
-
- -- Rafael Laboissiere <rafael@debian.org>, Sun Feb 1 13:43:54 CET 2004
-
-
diff --git a/config/bootstrap.sh b/config/bootstrap.sh
deleted file mode 100644
index c9296aa..0000000
--- a/config/bootstrap.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-run () {
- echo -n Running `$1 --version | sed q`...
- $* > /dev/null
- echo " done"
-}
-
-
-if test ! -f config/configure.ac ; then
- echo "$0: This script must be run from the Qhull top directory."
- exit 1
-fi
-
-echo -n Copying autoconf and automake files...
-cp config/configure.ac .
-cp config/Makefile-am-main Makefile.am
-for d in html eg ; do
- cp config/Makefile-am-$d $d/Makefile.am
-done
-for d in libqhull ; do
- cp config/Makefile-am-$d src/$d/Makefile.am
-done
-echo -en ' done\nCopying program sources to src/libqhull...'
-sources="src/qconvex/qconvex.c src/qdelaunay/qdelaun.c src/qhalf/qhalf.c \
- src/qhull/unix.c src/qvoronoi/qvoronoi.c src/rbox/rbox.c src/testqset/testqset.c"
-cp $sources src/libqhull
-echo " done"
-
-run aclocal \
- && run libtoolize --force --copy \
- && run automake --foreign --add-missing --force-missing --copy \
- && run autoconf
diff --git a/config/changelog b/config/changelog
deleted file mode 100644
index eab5f24..0000000
--- a/config/changelog
+++ /dev/null
@@ -1,128 +0,0 @@
-Qhull 2012.1 2012/02/02
- - Add config to distribution
- - Add testqset to config build
- - config/bootstrap.sh copies program files into src/libqhull
-
-Qhull 2011.2 (qhull6) 2011/12/02
- - Removed Make-conf.sh (from the qhull 2003.1 release)
- - The original changelog follows
- - Adjusted the Makefiles for the new directory structure.
- - Kept qh_QHpointer=0 (static global data structure, qh_qh). It is faster.
- Qhull 2012 may have a new interface which passes qh_qh as a parameter.
-
-Qhull 2009.1.2 2011/11/21
- - Revert to LF line endings [P. Cheeseman]
- - Remove out-of-date material from qhull-go.bat
- - Replaced QHULL-GO with a lnk file
-
-qhull 2009.1.1 2010/01/09
-- Patch release of 2009.1.
- qh_gethash allowed a negative result, causing overwrite or segfault
- See git:qhull/project/patch/qhull-2003.1/poly.c-qh_gethash.patch
- Compared results of q_test, q_eg, q_egtest with patched poly.c, qhull-2003.1
-
-qhull (2009.1, qhull5)
-
-This is a maintenance release done by Rafael Laboissiere <rafael@debian.org>.
- - src/rbox.c (main): Avoid problems of evaluation order when
- pre-incrementing arguments of strtod
- - src/io.c (qh_produce_output), src/stat.c (qh_initstatistics): Use %lu
- instead of %d in the format string for arguments of type size_t
- - html/qhull.man, html/rbox.man: Fix several syntax, macros, and hyphen
- problems in man pages
- - The Autotools files have been generated with modern version of autoconf (2.63),
- automake/aclocal (1.10.2), and libtool (2.2.6)
- - Some character issues in the man pages are fixed
-
-qhull (2003.1-1, qhull5) unstable; urgency=low
-
- * New upstream release. There are backward incompatibilities in the code
- and the soversion was bumped to libqhull5.
- * debian/rules:
- - Major rewrite of build and install rules, since we are using now the
- upstream tarball generated with "make dist".
- - Added config rule.
- - Use dpatch to patch src/user.h (enable qh_QHpointer).
- * debian/control:
- - Removed build-dependencies on autoconf, automake, and libtool.
- - Build-depends on dpatch.
- - Changed section of libqhull-dev package to libdevel.
- * debian/libqhull-dev.files: Added usr/share/doc/libqhull5/src
- directory.
-
- -- Rafael Laboissiere <rafael@debian.org> Sun, 1 Feb 2004 01:14:13 +0100
-
-qhull (2002.1-4) unstable; urgency=low
-
- * src/Make-config.sh: Patched upstream file for proper initialization of
- the Autotools.
- * debian/install-src-html.sh: Added script for including src/*.htm
- source documentation files into html doc dir.
- * debian/control:
- - Bumped Standards-Version to 3.6.1 (no changes needed).
- - Changed build-dependencies to autoconf and automake1.7 (instead of
- autoconf2.13 and automake1.6). Added eperl.
- * debian/libqhull-dev.files: Added dir usr/share/doc/libqhull4/src.
- * debian/manpage.in: Added template for missing man pages.
- * debian/rules:
- - Call debian/install-src-html.sh.
- - Generate manpages for qconvex, qdelaunay, qhalf, and qvoronoi
- commands. Lintian is happy now.
-
- -- Rafael Laboissiere <rafael@debian.org> Thu, 18 Dec 2003 21:20:14 +0100
-
-qhull (2002.1-3) unstable; urgency=low
-
- * New maintainer (as per http://lists.debian.org/debian-devel/1999
- /debian-devel-199911/msg01061.html).
- * debian/rules: Use the upstream script Make-config.sh, which sets up
- the autoconf/automake/libtool files. Also, clean up all the generated
- files in the clean rule.
- * debian/control: Bumped Standards-Version to 3.5.7. Added
- Build-Dependencies to autoconf/automake/libtool.
-
- -- Rafael Laboissiere <rafael@debian.org> Wed, 25 Sep 2002 10:39:30 +0200
-
-qhull (2002.1-2) unstable; urgency=low
-
- * use shared char* qh_version in library
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Sat, 7 Sep 2002 10:34:13 -0600
-
-qhull (2002.1-1) unstable; urgency=low
-
- * new upstream source
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Thu, 5 Sep 2002 20:51:10 -0600
-
-qhull (3.1-5) unstable; urgency=low
-
- * rephrase descriptions (closes: #141027)
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Thu, 11 Apr 2002 22:12:33 -0600
-
-qhull (3.1-4) unstable; urgency=low
-
- * include executables qconvex, qhalf, qvoronoi, qdelaunay
- * break executables out into separate package qhull-bin
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Wed, 27 Mar 2002 20:26:44 -0700
-
-qhull (3.1-3) unstable; urgency=low
-
- * rename executable qhull-rbox back to rbox
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Mon, 25 Mar 2002 09:13:57 -0700
-
-qhull (3.1-2) unstable; urgency=low
-
- * src/qconvex.c did not belong in the library
- * qh_version was multiply defined, now defined only in qhull.c
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Mon, 25 Mar 2002 08:55:45 -0700
-
-qhull (3.1-1) unstable; urgency=low
-
- * Initial Release. (closes: #108115)
-
- -- Barak Pearlmutter <bap@cs.unm.edu> Sun, 24 Mar 2002 21:53:13 -0700
diff --git a/config/configure.ac b/config/configure.ac
deleted file mode 100644
index e68ed2b..0000000
--- a/config/configure.ac
+++ /dev/null
@@ -1,25 +0,0 @@
-dnl configure.ac for the qhull package
-dnl Author: Rafael Laboissiere <rafael@debian.org>
-dnl Created: Mon Dec 3 21:36:21 CET 2001
-dnl Draft update for 2011.2: B. Barber, dec'11
-
-AC_INIT(qhull, 6.3.1)
-AC_CONFIG_SRCDIR(src/libqhull/libqhull.c)
-
-AC_CONFIG_AUX_DIR(config)
-AC_CONFIG_MACRO_DIR(config)
-
-AM_INIT_AUTOMAKE
-
-AC_PROG_CC
-AC_PROG_LIBTOOL
-
-AC_CONFIG_FILES([
- Makefile
- src/libqhull/Makefile
- html/Makefile
- eg/Makefile
- config/Makefile
-])
-
-AC_OUTPUT
diff --git a/config/patches/00list b/config/patches/00list
deleted file mode 100644
index 895e714..0000000
--- a/config/patches/00list
+++ /dev/null
@@ -1,2 +0,0 @@
-QHpointer.dpatch
-make-new-msg.dpatch
diff --git a/config/patches/QHpointer.dpatch b/config/patches/QHpointer.dpatch
deleted file mode 100644
index 16f04f5..0000000
--- a/config/patches/QHpointer.dpatch
+++ /dev/null
@@ -1,35 +0,0 @@
-#! /bin/sh -e
-## QHpointer.dpatch by Rafael Laboissiere <rafael@debian.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Access Qhull globals via a pointer to allocated memory
-
-[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
-patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
-
-if [ $# -ne 1 ]; then
- echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
- exit 1
-fi
-case "$1" in
- -patch)
- patch $patch_opts -p1 < $0;;
- -unpatch)
- patch $patch_opts -p1 -R < $0;;
- *)
- echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
- exit 1;;
-esac
-
-exit 0
---- qhull-orig/src/user.h 2002-04-29 11:01:46.000000000 +0200
-+++ qhull/src/user.h 2004-02-02 11:04:47.000000000 +0100
-@@ -509,7 +509,7 @@
- see:
- user_eg.c for an example
- */
--#define qh_QHpointer 0
-+#define qh_QHpointer 1
- #if 0 /* sample code */
- qhT *oldqhA, *oldqhB;
-
diff --git a/config/patches/make-new-msg.dpatch b/config/patches/make-new-msg.dpatch
deleted file mode 100644
index 8cb77cc..0000000
--- a/config/patches/make-new-msg.dpatch
+++ /dev/null
@@ -1,40 +0,0 @@
-#! /bin/sh -e
-## QHpointer.dpatch by Rafael Laboissiere <rafael@debian.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Access Qhull globals via a pointer to allocated memory
-
-[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
-patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
-
-if [ $# -ne 1 ]; then
- echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
- exit 1
-fi
-case "$1" in
- -patch)
- patch $patch_opts -p1 < $0;;
- -unpatch)
- patch $patch_opts -p1 -R < $0;;
- *)
- echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
- exit 1;;
-esac
-
-exit 0
---- qhull-orig/src/io.c 2004-01-31 12:00:15.000000000 +0100
-+++ qhull/src/io.c 2004-02-06 09:54:18.000000000 +0100
-@@ -4017,11 +4017,8 @@
- qh rbox_command[strlen(qh rbox_command)-1]= '\0';
- if (!strcmp (qh rbox_command, "./rbox D4"))
- fprintf (qh ferr, "\n\
--This is the qhull test case. If any errors or core dumps occur,\n\
--recompile qhull with 'make new'. If errors still occur, there is\n\
--an incompatibility. You should try a different compiler. You can also\n\
--change the choices in user.h. If you discover the source of the problem,\n\
--please send mail to qhull_bug@qhull.org.\n\
-+This is the qhull test case. If any errors or core dumps occur,\n\
-+fill a bug report against the libqhull<soversion> Debian package.\n\
- \n\
- Type 'qhull' for a short list of options.\n");
- }
diff --git a/eg/make-vcproj.sh b/eg/make-vcproj.sh
deleted file mode 100644
index faee9eb..0000000
--- a/eg/make-vcproj.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/bash
-#
-# make-vcproj.sh -- Make sln and vcproj files from CMakeLists.txt and qhull-all.pro
-#
-# [jan'12] Additional changes made by hand for qhull 2012.1. This file updated but not tested.
-#
-# $Id: //main/2011/qhull/eg/make-vcproj.sh#5 $$Change: 1476 $
-# $DateTime: 2012/01/28 09:37:56 $$Author: bbarber $
-
-if [[ ! -f CMakeLists.txt || ! -f src/qhull-all.pro ]]; then
- echo "Excute eg/make-vcproj.sh from qhull directory with CMakeLists.txt and src/qhull-all.pro"
- exit
-fi
-
-echo "Set up build directories..."
-if [[ ! -d build-prev ]]; then
- echo "Backup previous build"
- cp -r build build-prev && rm -r build
-fi
-rm -r buildvc buildqt
-mkdir -p build
-mkdir -p buildvc
-mkdir -p buildqt
-echo "Create vcproj files with cmake and qmake..."
-cd buildvc && cmake -G "Visual Studio 8 2005" .. && cmake ..
-cd ..
-cd buildqt && qmake -tp vc -r ../src/qhull-all.pro
-cd ..
-if [[ ! -f CMakeLists.txt || ! -f buildvc/qhull.vcproj || ! -f buildqt/qhulltest/qhulltest.vcproj ]]; then
- echo "qmake and cmake did not build vcproj files in buildvc/ and buildqt"
- exit
-fi
-
-
-for f in buildvc/*.vcproj buildqt/qhulltest/*.vcproj; do
- echo $f
- if [[ ! ${f##*INSTALL*} || ! ${f##*ALL_BUILD*} || ! ${f##*ZERO_CHECK*} ]]; then
- continue
- fi
- dest=build/${f##*\/}
- sed -r -e 's|[cC]:\\bash\\local\\qhull|..|g' \
- -e 's|[cC]:/bash/local/qhull|..|g' \
- -e '\|CMake| d' \
- -e 's/;CMAKE_INTDIR=..quot;[A-Za-z]*..quot;//' \
- -e 's/LinkIncremental="2"/LinkIncremental="1"/' \
- -e 's/RuntimeLibrary[=]/RuntimeTypeInfo="false" RuntimeLibrary=/' \
- -e 's/.*RuntimeTypeInfo."TRUE".*//' \
- -e 's/buildvc/build/g' \
- -e 's/buildqt/build/g' \
- -e 's/\.\.\\\.\./../g' \
- -e 's|\.\./\.\.|..|g' \
- -e 's/c:\\qt\\[0-9]\.[0-9]\.[0-9]/\$(QTDIR)/g' \
- -e 's|..\\build\\[a-zA-Z]*[\\/]([_a-z0-9]*.pdb)|..\\bin\\\1|g' \
- -e 's|..\\build\\[a-zA-Z]*[\\/]([_a-z0-9]*.exe)|..\\bin\\\1|g' \
- -e 's|..\\build\\[a-zA-Z]*[\\/]([_a-z0-9]*.lib)|..\\lib\\\1|g' \
- -e 's|..\\build\\[a-zA-Z]*[\\/]([_a-z0-9]*.dll)|..\\bin\\\1|g' \
- -e 's| [a-zA-Z]*[\\/]([_a-z0-9]*.lib)| ..\\lib\\\1|g' \
- -e 's/"([_a-z0-9]*.exe)/"..\\bin\\\1/g' \
- $f > $dest
-done
-
-echo -e '\nExcept for qhulltest.vcproj,\n*.vcproj: [mar'14 none] delete empty File in Files section near end of vcproj'
-echo -e '\nExcept for qhulltest.vcproj,\n*.vcproj: [mar'14 where?] rename debug targets to qhull_d.dll, etc.'
-
-# If need to rebuild sln
-sed -e '\|Project.*ALL_BUILD|,\|EndProject$| d' \
- -e '\|Project.*INSTALL|,\|EndProject$| d' \
- -e '\|Project.*ZERO_CHECK|,\|EndProject$| d' \
- buildvc/qhull.sln >build/qhull.sln
-
-echo
-echo 'qhull.sln: Identify the GUID on the first line of each list.'
-echo 'qhull.sln: Remove first part of Global section down to this GUID'
-echo 'qhull.sln: Remove this GUID from each GUID list -- postProject\n.* > postProject'
-echo 'qhull.sln: Remove five empty project sections'
-echo 'qhull.sln: Save as PC'
-echo '\nExcept for libqhullcpp, libqhullpcpp, qhulltest, user_eg3\n*.vcproj: Remove "..\src\libqhullcpp;" from AdditionalIncludeDirectories'
-echo
-echo 'Open qhull.sln with DevStudio and add qhulltest.vcproj'
-echo 'Add dependencies on libqhull libqhull6_p and qhullcpp'
-echo 'Change Linker>OutputFile to qhulltest.exe'
-echo 'Remove qhulltest via Configuration Manager from Release, Debug, etc.'
-
-
diff --git a/eg/q_eg b/eg/q_eg
index 4d8dd74..2e5cba5 100755
--- a/eg/q_eg
+++ b/eg/q_eg
@@ -1,72 +1,77 @@
#!/bin/sh
# writes examples to eg/
# see html/qh_eg.htm
if ! qconvex >/dev/null 2>&1; then
if [ ! -d bin ]; then
echo Run eg/q_eg from the Qhull directory
exit
fi
if [ ! -e bin/qconvex -a ! -e bin/qconvex.exe ]; then
echo 'Build qhull first. qconvex is missing from bin/ directory and $PATH'
exit
fi
if ! qconvex >/dev/null 2>&1; then
PATH=$PWD/bin:$PATH
fi
fi
mkdir -p eg
+echo ==============================
+echo ========= eg/q_eg ============
+echo == Create geomview examples ==
+echo ==============================
+echo
set -v
rbox c D3 | qconvex s G >eg/eg.01.cube
rbox c d G2.0 | qconvex s G >eg/eg.02.diamond.cube
rbox s 100 D3 | qconvex s G >eg/eg.03.sphere
rbox s 100 D2 | qconvex s G >eg/eg.04.circle
rbox 10 l | qconvex s G >eg/eg.05.spiral
rbox 1000 D2 | qconvex s C-0.03 Qc Gapcv >eg/eg.06.merge.square
rbox 1000 D3 | qconvex s G >eg/eg.07.box
rbox c G0.4 s 500 | qconvex s G >eg/eg.08a.cube.sphere
rbox d G0.6 s 500 | qconvex s G >eg/eg.08b.diamond.sphere
rbox 100 L3 G0.5 s | qconvex s G >eg/eg.09.lens
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG0 >eg/eg.10a.sphere.visible
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG-0 >eg/eg.10b.sphere.beyond
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG0 PG >eg/eg.10c.sphere.horizon
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QV0 PgG >eg/eg.10d.sphere.cone
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga >eg/eg.10e.sphere.new
rbox 100 s P0.5,0.5,0.5 | qhull s Ga QV0g Q0 >eg/eg.14.sphere.corner
rbox 500 W0 | qconvex s QR0 Qc Gvp >eg/eg.15a.surface
rbox 500 W0 | qconvex s QR0 Qt Qc Gvp >eg/eg.15b.triangle
rbox 500 W0 | qconvex s QR0 QJ5e-2 Qc Gvp >eg/eg.15c.joggle
echo 2 = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 >eg/eg.data.17
echo 25 >>eg/eg.data.17
rbox 15 D2 B0.3 W0.25 c G0.5 | tail -n +3 >>eg/eg.data.17
rbox 6 r s D2 B0.2 | tail -n +3 >>eg/eg.data.17
qdelaunay s Qt <eg/eg.data.17 GnraD2 >eg/eg.17a.delaunay.2
qdelaunay s <eg/eg.data.17 GnraD2 >eg/eg.17b.delaunay.2i
qdelaunay s <eg/eg.data.17 C-0 Ga >eg/eg.17c.delaunay.2-3
qvoronoi s QJ <eg/eg.data.17 Gna >eg/eg.17d.voronoi.2
qvoronoi s <eg/eg.data.17 Gna >eg/eg.17e.voronoi.2i
rbox c G0.1 d | qdelaunay Gt Qz >eg/eg.17f.delaunay.3
rbox 10 D2 d | qdelaunay s Qu G >eg/eg.18a.furthest.2-3
rbox 10 D2 d | qdelaunay s Qu Pd2 G >eg/eg.18b.furthest-up.2-3
rbox 10 D2 d | qvoronoi s Qu Gv >eg/eg.18c.furthest.2
rbox 10 D3 | qvoronoi s FQ QV5 p | qconvex s G >eg/eg.19.voronoi.region.3
rbox r s 20 Z1 G0.2 | qconvex s QR1 G >eg/eg.20.cone
rbox 200 s | qconvex s Qc R0.014 Gpav >eg/eg.21b.roundoff.fixed
rbox 1000 s| qconvex s C0.01 Qc Gcrp >eg/eg.22a.merge.sphere.01
rbox 1000 s| qconvex s C-0.01 Qc Gcrp >eg/eg.22b.merge.sphere.-01
rbox 1000 s| qconvex s C0.05 Qc Gcrpv >eg/eg.22c.merge.sphere.05
rbox 1000 s| qconvex s C-0.05 Qc Gcrpv >eg/eg.22d.merge.sphere.-05
rbox 1000 | qconvex s Gcprvah C0.1 Qc >eg/eg.23.merge.cube
rbox 5000 D4 | qconvex s GD0v Pd0:0.5 C-0.02 C0.1 >eg/eg.24.merge.cube.4d-in-3d
rbox 5000 D4 | qconvex s s C-0.02 C0.1 Gh >eg/eg.30.4d.merge.cube
rbox 20 D3 | qdelaunay s G >eg/eg.31.4d.delaunay
rbox 30 s D4 | qconvex s G Pd0d1d2D3 >eg/eg.32.4d.octant
rbox 10 r s Z1 G0.3 | qconvex G >eg/eg.33a.cone
rbox 10 r s Z1 G0.3 | qconvex FQ FV n | qhalf G >eg/eg.33b.cone.dual
rbox 10 r s Z1 G0.3 | qconvex FQ FV n | qhalf FQ s Fp | qconvex G >eg/eg.33c.cone.halfspace
echo ==the following should generate flipped and concave facets== >/dev/null
rbox 200 s | qhull Q0 s R0.014 Gav Po >eg/eg.21a.roundoff.errors
echo ==the preceeding should report flipped and concave facets== >/dev/null
diff --git a/eg/q_egtest b/eg/q_egtest
index e264954..6b9ab81 100755
--- a/eg/q_egtest
+++ b/eg/q_egtest
@@ -1,47 +1,52 @@
#!/bin/sh
# writes examples to eg/
if ! qconvex >/dev/null 2>&1; then
if [ ! -d bin ]; then
echo Run eg/q_eg from the Qhull directory
exit
fi
if [ ! -e bin/qconvex -a ! -e bin/qconvex.exe ]; then
echo 'Build qhull first. qconvex is missing from bin/ directory and $PATH'
exit
fi
if ! qconvex >/dev/null 2>&1; then
PATH=$PWD/bin:$PATH
fi
fi
-mkdir -p
+mkdir -p eg
+echo ==============================
+echo ========= eg/q_egtest ========
+echo == Create geomview tests =====
+echo ==============================
+echo
set -v
rbox d D3 | qconvex s Gnrv Tc Tv >eg/eg.t01.spheres.3
rbox d D2 | qconvex s Gnv Tc Tv >eg/eg.t02.spheres.2
rbox d D3 | qconvex s Gnrp Tc Tv >eg/eg.t03.points.3
rbox d D2 | qconvex s Gnp Tc Tv >eg/eg.t04.points.2
rbox c D4 | qconvex s C0.05 GnpcD3 Pd3:0.5 Tc Tv >eg/eg.t05.centrum.points.4-3
rbox d D3 | qconvex s Gnrc Tc Tv >eg/eg.t06.centrums.3.precise
rbox d D3 | qconvex s C0.05 Gnrc Tc Tv >eg/eg.t07.centrums.3
rbox d D2 | qconvex s C0.05 Gc Tc Tv >eg/eg.t08.centrums.2
rbox d D3 | qconvex s Gnha Tc Tv >eg/eg.t09.intersect.3
rbox d D3 | qconvex s GaD0 Pd0 Tc Tv >eg/eg.t10.faces.3-2
rbox d D3 | qconvex s GnrpD0 Pd0 Tc Tv >eg/eg.t11.points.3-2
rbox d D3 | qconvex s C0.05 GnrcD0 Pd0 Tc Tv >eg/eg.t12.centrums.3-2
rbox d D3 | qconvex s GnhaD0 Pd0 Tc Tv >eg/eg.t13.intersect.3-2
rbox d D3 | qconvex s GnrvD0 Pd0 Tc Tv >eg/eg.t14.spheres.3-2
rbox c D4 | qconvex s GvD0 Pd0:0.5 Tc Tv >eg/eg.t15.spheres.4-3
rbox c D4 | qhull s Q0 C0 GpD0 Pd0:0.5 Tc Tv >eg/eg.t16.points.4-3
rbox c D4 | qconvex s GahD0 Pd0:0.5 Tc Tv >eg/eg.t17.intersect.4-3
rbox 100 s | qconvex s C-0.05 Qc Gicvprh Tc Tv >eg/eg.t18.imprecise.3
rbox 30 s D4 | qconvex s GhD0 Pd0d1d2D3 Tc >eg/eg.t19.intersect.precise.4-3
rbox 100 s P1,1,1 | qconvex s QG-0 Pgp Tc G >eg/eg.t20.notvisible
rbox 100 s | qconvex s QV-10 Pgp Tc G >eg/eg.t21.notvertex
rbox 100 r D2 P1,1 | qhull s Pd0:0.7 PD0:0.8 QgG0 G Tv >eg/eg.t22.split
rbox 100 D2 c G1.0 | qvoronoi s A-0.95 Gna Tv >eg/eg.t23.voronoi.imprecise
rbox 30 s D4 | qconvex s Gh Pd0d1d2D3 Tc >eg/eg.t24.intersect.precise.4d
echo ==the following generates an error== >/dev/null
rbox 1000 D4 | qhull Q0 s Po R0.005 Ga Tc Tv >eg/eg.t25.neighbors.4d
echo ==the previous should generate an error== >/dev/null
diff --git a/eg/q_test b/eg/q_test
index 7e8109a..aa22951 100755
--- a/eg/q_test
+++ b/eg/q_test
@@ -1,403 +1,410 @@
#!/bin/sh
#
# NOTE: all tests duplicated in q_test.bat
if ! qconvex >/dev/null 2>&1; then
if [ ! -d bin ]; then
echo Run eg/q_test from the Qhull directory
exit
fi
if [ ! -e bin/qconvex -a ! -e bin/qconvex.exe ]; then
echo 'Build qhull first. qconvex is missing from bin/ directory and $PATH'
exit
fi
if ! qconvex >/dev/null 2>&1; then
PATH=$PWD/bin:$PATH
fi
fi
if ! user_eg >/dev/null; then
echo user_eg failed to run. It uses the shared qhull library
echo 'On Linux, export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH'
fi
+echo ==============================
+echo ========= eg/q_test ==========
+echo == Check qhull programs ======
+echo ==============================
+echo
+echo ==============================
+echo == check user_eg, user_eg2, and user_eg3
+echo == errors if 'user_eg' and 'user_eg2' not found
+echo ==============================
set -v
-echo === errors if 'user_eg' and 'user_eg2' not found ===
-echo === check user_eg ${d:-`date`} =====================
user_eg "QR1 p n Qt" "v p" Fp
user_eg2 "QR1 p" "v p" Fp
user_eg3 rbox "10 D2" "2 D2" qhull "p"
echo === check front ends ${d:-`date`} ==================
qconvex -
qconvex .
qconvex
rbox c D3 | qconvex s n Qt
rbox c D2 | qconvex s 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
rbox c D6 | qconvex FA TF500
rbox c P0 d D2 | qconvex p Fa Fc FP FI Fn FN FS Fv Fx
rbox c d D2 | qconvex s i QV0
rbox c | qconvex Q0
qvoronoi -
qvoronoi .
qvoronoi
rbox c P0 D2 | qvoronoi s o
rbox c P0 D2 | qvoronoi Fi Tv
rbox c P0 D2 | qvoronoi Fo
rbox c P0 D2 | qvoronoi Fv
rbox c P0 D2 | qvoronoi s Qu Qt Fv
rbox c P0 D2 | qvoronoi Qu Fo
rbox c G1 d D2 | qvoronoi s p
rbox c G1 d D2 | qvoronoi QJ p
rbox c P-0.1 P+0.1 P+0.1 D2 | qvoronoi s Fc FP FQ Fn FN
rbox P0 c D2 | qvoronoi s Fv QV0
qdelaunay -
qdelaunay .
qdelaunay
rbox c P0 D2 | qdelaunay s o
rbox c P0 D2 | qdelaunay i
rbox c P0 D2 | qdelaunay Fv
rbox c P0 D2 | qdelaunay s Qu Qt Fv
rbox c G1 d D2 | qdelaunay s i
rbox c G1 d D2 | qhull d Qbb Ft
rbox c G1 d D2 | qhull d Qbb QJ s Ft
rbox M3,4 z 100 D2 | qdelaunay s
rbox c P-0.1 P+0.1 P+0.1 D2 | qdelaunay s Fx Fa Fc FP FQ Fn FN
rbox P0 P0 c D2 | qdelaunay s FP QV0
qhalf -
qhalf .
qhalf
rbox d | qhull FQ n | qhalf s Qt H0,0,0 Fp
rbox c | qhull FQ FV n | qhalf s i
rbox c | qhull FQ FV n | qhalf o
rbox d D2 | qhull FQ n | qhalf s H0 Fc FP Fn FN FQ Fv Fx
echo === check quality of Qhull for ${d:-`hostname`} ${d:-`date`}
rbox 1000 W0 | qhull QR2 QJ s Fs Tv
rbox 1000 W0 | qhull QR2 s Fs Tv
rbox 1000 s | qhull C0.02 Qc Tv
rbox 500 s D4 | qhull C0.01 Qc Tv
rbox 1000 s | qhull C-0.02 Qc Tv
rbox 1000 s D4 | qhull C-0.01 Qc Tv
rbox 200 s D5 | qhull C-0.01 Qx Qc Tv
rbox 100 s D6 | qhull C-0.001 Qx Qc Tv
rbox 1000 W1e-4 | qhull C-1e-6 Qc Tv
rbox 1000 W5e-4 D4 | qhull C-1e-5 Qc Tv
rbox 400 W1e-3 D5 | qhull C-1e-5 Qx Qc Tv
echo === check input format etc. ${d:-`date`}
qhull <<EOF
2 4 #;laskdjf
1 0 1 1 1 2 0 0
EOF
qhull <<EOF
2 4 #;laskdjf
1 0 1 1 1 2 0 0 0
EOF
qhull <<EOF
2 4 #;laskdjf
1 0 1 1 1 2 0
EOF
qhull <<EOF
2
4 #;laskdjf
1 #kjdfasdf
0 1 1 1 2 0
EOF
qhull <<EOF
2 4 1 0 1 1 1 2 0 0
EOF
qhull d Qz <<EOF
2 5 1 0 1 1 0 1 0 0 0
EOF
qhull d Q8 Qz <<EOF
2 5 1 0 1 1 0 1 0 0 0
EOF
rbox d h | qhull Fd FV n FD Tcv | qhull Fd H Fp Tcv
rbox 10 h | qhull Fd FD p Tcv | qhull Fd d Tcv
echo === check rbox ${d:-`date`}
rbox 3 n D2
rbox 3 D2
rbox 3 h D2
rbox 3 z D2
rbox 3 z h D2
rbox 3 B10 D2
rbox 3 z B10 D2
rbox 4 L2 r D2
rbox 8 L2 D2
rbox 4 L4 r D3
rbox 4 L4 s D5 W1e-3
rbox y
rbox 10 M3,4
rbox 10 L2 s D3 | qhull Tcv
rbox 10 L4 s W1e-3 D3 | qhull Tcv
rbox 10 L6 D3 | qhull Tcv
rbox 10 L1.1 s D4 | qhull Tcv
rbox y r 100 W0 O0.5 | qhull s p Tcv
rbox x r 100 W0 O0.5 | qhull s Tcv
rbox 12 D8 | qhull Tcv
rbox 12 D9 | qhull Tcv
rbox 1000 D4 | qhull s i A-0.97 C0.2 A0.7 Tcv
rbox 3 D2 | qhull Qb0B1:-2 p
rbox 100 r D2 | qhull Pd0:0.7 PD0:0.8 n Tcv
rbox 1000 s | qhull C0.05 Tcv
rbox 1000 s t | qhull Qm C0.05 Tcv
rbox 500 D2 | qhull n A-0.95 C0.1 Tcv
rbox 500 s P1,1,1 | qhull QgG0 Pp Tcv
rbox d | qhull m
rbox d | qhull FM
rbox c D2 | qhull Tcv Q0
rbox d D2 | qhull Tcv
rbox c D3 | qhull Tcv Q0
rbox d D3 | qhull Tcv
rbox c D4 | qhull Tcv Q0
rbox d D4 | qhull Tcv
rbox c D5 | qhull Tcv Q0
rbox d D5 | qhull Tcv
rbox c D6 | qhull Tcv Q0
rbox d D6 | qhull Tcv
rbox d D7 | qhull Tcv
rbox c D2 | qhull Tcv C-0
rbox c D3 | qhull Tcv C-0
rbox c D4 | qhull Tcv C-0
rbox c D5 | qhull Tcv C-0
rbox c D6 | qhull Tcv C-0
rbox c D7 | qhull Tv C-0
rbox 20 l D3 | qhull Tcv
rbox 100 s D2 | qhull Tcv
rbox 100 s D3 | qhull Tcv
rbox 100 s D4 | qhull Tcv
rbox 100 s c D4 | qhull Tcv
rbox 100 s d G1.5 D4 | qhull Tcv
rbox 100 s W1e-2 | qhull Tcv
rbox 100 | qhull Tcv
rbox 100 W1e-3 | qhull Tcv
rbox 100 r D2 | qhull Tcv
rbox 100 r s Z1 | qhull Tcv
rbox 100 r s Z1 G0.1 | qhull Tcv C-0
rbox 100 s Z1 G0.1 | qhull Tcv
rbox 100 s Z1e-5 G0.1 | qhull Tc Pp
echo === check qhull output formats ${d:-`date`}
rbox 5 r s D2 | qhull Tcv
rbox 5 r s D2 | qhull s
rbox 5 r s D2 | qhull s o
rbox 5 r s D2 | qhull f
rbox 5 r s D2 | qhull i
rbox 5 r s D2 | qhull m
rbox 5 r s D2 | qhull FM
rbox 5 r s D2 | qhull n
rbox 5 r s D2 | qhull p
rbox 5 r s D2 | qhull o
rbox 5 r s D2 | qhull Ft
rbox 5 r s D2 | qhull Fx
rbox 5 r s D2 | qhull p n i p p
rbox 10 D3 | qhull f Tcv
rbox 10 D3 | qhull i
rbox 10 D3 | qhull p
rbox 10 D3 | qhull o
rbox 10 D3 | qhull Fx
rbox 27 M1,0,1 | qhull Qc
rbox 50 D3 s | qhull C0.1 Qc Pd0d1d2 s p Tcv
rbox 10 D2 P0 P1e-15 | qhull d Qc FP s Tcv
rbox 100 s | qhull C-0.003 Qc FP s
rbox 100 s D2 | qhull C0.1 i Fx Tcv
rbox 4 s D3 | qhull Qc Ghipv Tcv
rbox 6 D4 | qhull f Tcv
rbox 6 D4 | qhull i
rbox 6 D4 | qhull p
rbox 6 D4 | qhull o
rbox 1000 s D2 | qhull FA Tcv
rbox 1000 s | qhull FA Tcv
rbox c D4 | qhull FA Tcv
rbox c D5 | qhull FA Tcv
rbox c D5 | qhull FA Qt Tcv
rbox 10 D2 | qhull d FA Tcv
rbox 10 D2 | qhull d Qu FA Tcv
rbox 10 D2 | qhull FA Tcv
rbox 10 c D2 | qhull Fx Tcv
rbox 1000 s | qhull FS Tcv
rbox 10 W0 D2 | qhull p Qc FcC Tcv
rbox 4 z h s D2 | qhull Fd s n FD Tcv
rbox 6 s D3 | qhull C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
rbox P0.5,0.5 P0.5,0.5 W0 5 D2 | qhull d FN Qc
rbox 10 D3 | qhull Fa PA5
rbox 10 D3 | qhull Fa PF0.4
echo === test Qt ${d:-`date`}
rbox c | qhull Qt s o Tcv
rbox c | qhull Qt f i
rbox c | qhull Qt m FM n
rbox c | qhull Qt p o
rbox c | qhull Qt Fx
rbox c | qhull Qt FA s Fa
rbox 6 r s c G0.1 D2 | qhull Qt d FA Tcv
rbox 6 r s c G0.1 D2 | qhull d FA Tcv
rbox 6 r s c G0.1 D2 | qhull Qt v p Tcv
rbox c | qhull Qt C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
rbox 6 r s c G0.1 D2 P0.1,0.1 | qhull s FP d FO Qt
rbox 100 W0 | qhull Tv Q11
echo === test unbounded intersection ${d:-`date`}
rbox c | qhull PD0:0.5 n | qhull H0 Fp Tcv
rbox 1000 W1e-3 D3 | qhull PA8 Fa FS s n Tcv
rbox 1000 W1e-3 D3 | qhull C-0.01 PM10 Fm n Tcv Qc
rbox 1000 W1e-3 D3 | qhull C-0.01 PA8 PG n Tcv Qc
rbox 10 | qhull FO Tz TO q_test.log.1
cat q_test.log.1
echo === check Delaunay/Voronoi ${d:-`date`}
rbox 10 D2 | qhull d Tcv
rbox 10 D2 | qhull d Tcv Qz
rbox 10 D3 | qhull d Tcv
rbox c | qhull d Qz Ft Tcv
rbox 10 s D2 c | qhull d Tcv
rbox 10 s D2 | qhull d Tcv Q8 Qz
rbox 10 D2 | qhull d Tcv p
rbox 10 D2 | qhull d Tcv i
rbox 10 D2 | qhull d Tcv o
rbox 10 D2 | qhull v Tcv o
rbox 10 D2 | qhull v Tcv p
rbox 10 D2 | qhull v Tcv G
rbox 10 D2 | qhull v Tcv Fv
rbox 10 D2 | qhull v Tcv Fi
rbox 10 D2 | qhull v Tcv Fo
rbox 10 D2 | qhull v Qu o Fv Fi Fo Tcv
rbox 10 D3 | qhull v Fv Tcv
rbox 10 D3 | qhull v Fi Tcv
rbox 10 D3 | qhull v Fo Tcv
rbox 10 D3 | qhull v Qu o Fv Fi Fo Tcv
rbox 5 D2 | qhull v f FnN o
echo === check Halfspace ${d:-`date`}
rbox 100 s D4 | qhull FA FV n s Tcv | qhull H Fp Tcv | qhull FA Tcv
rbox d D3 | qhull FQ n s FD Tcv | qhull Fd H0.1,0.1 Fp FQ Tcv
rbox 5 r D2 | qhull s n Tcv | qhull H0 Fp Tcv
echo === check qhull ${d:-`date`}
rbox 10 s D3 | qhull Tcv
rbox 10 s D3 | qhull f Pd0:0.5 Pd2 Tcv
rbox 10 s D3 | qhull f Tcv PD2:-0.5
rbox 10 s D3 | qhull QR-1
rbox 10 s D3 | qhull QR-40
rbox 1000 D3 | qhull Tcvs
rbox 100 D3 | qhull T8 Tz TO q_test.log.1
tail -n -10 q_test.log.1
rm q_test.log.1
rbox 100 s D3 | qhull TcvV-2
rbox 100 s D3 | qhull TcvC2
rbox 100 s D3 | qhull TcvV2
rbox 100 s D3 | qhull T1cvV2P2
rbox 100 s D3 | qhull TcvF100
rbox 100 s D3 | qhull Qf Tcv
rbox 100 D3 | qhull Tcv
rbox 100 D3 | qhull Qs Tcv
rbox 100 D5 | qhull Qs Tcv
rbox 100 D3 | qhull Qr Tcv
rbox 100 D3 | qhull Qxv Tcv
rbox 100 D3 | qhull Qi f Pd0 Pd1 Pd2 Tcv
rbox c d | qhull Qc f Tcv
rbox c d | qhull Qc p Tcv
rbox 100 D3 | qhull QbB FO Tcv
rbox 1000 D2 B1e6 | qhull d Qbb FO Tcv
rbox 10 D3 | qhull QbB p Tcv
rbox 10 D3 | qhull Qbb p Tcv
rbox 10 D3 | qhull Qb0:-10B2:20 p Tcv
rbox 10 D3 | qhull Qb0:-10B2:20 p Tcv | qhull QbB p Tcv
rbox 10 D3 | qhull Qb1:0B1:0 d Tcv Q8
rbox 10 D3 | qhull Qb1:0B1:0B2:0 d Tcv Q8
rbox 10 D3 | qhull Qb1:0 d Tcv
rbox 10 D3 | qhull Qb1:0B1:0 Tcv
echo "== next command will error ${d:-`date`} =="
rbox 10 D2 | qhull Qb1:1B1:1 Tcv
rbox 200 L20 D2 t | qhull FO Tcv C-0
rbox 1000 L20 t | qhull FO Tcv C-0
rbox 200 L20 D4 t | qhull FO Tcv C-0
rbox 200 L20 D5 t | qhull FO Tcv Qx
rbox 1000 W1e-3 s D2 t | qhull d FO Tcv Qu Q0
rbox 1000 W1e-3 s D2 t | qhull d FO Tcv Qu C-0
echo === check joggle and TRn ${d:-`date`}
rbox 100 W0 | qhull QJ1e-14 Qc TR100 Tv
rbox 100 W0 | qhull QJ1e-13 Qc TR100 Tv
rbox 100 W0 | qhull QJ1e-12 Qc TR100 Tv
rbox 100 W0 | qhull QJ1e-11 Qc TR100 Tv
rbox 100 W0 | qhull QJ1e-10 Qc TR100 Tv
rbox 100 | qhull d QJ Qb0:1e4 QB0:1e5 Qb1:1e4 QB1:1e6 Qb2:1e5 QB2:1e7 FO Tv
echo === check precision options ${d:-`date`}
rbox 100 D3 s | qhull E0.01 Qx Tcv FO
rbox 100 D3 W1e-1 | qhull W1e-3 Tcv
rbox 100 D3 W1e-1 | qhull W1e-2 Tcv Q0
rbox 100 D3 W1e-1 | qhull W1e-2 Tcv
rbox 100 D3 W1e-1 | qhull W1e-1 Tcv
rbox 15 D2 P0 P1e-14,1e-14 | qhull d Quc Tcv
rbox 15 D3 P0 P1e-12,1e-14,1e-14 | qhull d Qcu Tcv
rbox 1000 s D3 | qhull C-0.01 Tcv Qc
rbox 1000 s D3 | qhull C-0.01 V0 Qc Tcv
rbox 1000 s D3 | qhull C-0.01 U0 Qc Tcv
rbox 1000 s D3 | qhull C-0.01 V0 Qcm Tcv
rbox 1000 s D3 | qhull C-0.01 Qcm Tcv
rbox 1000 s D3 | qhull C-0.01 Q1 FO Tcv Qc
rbox 1000 s D3 | qhull C-0.01 Q2 FO Tcv Qc
rbox 1000 s D3 | qhull C-0.01 Q3 FO Tcv Qc
rbox 1000 s D3 | qhull C-0.01 Q4 FO Tcv Qc
echo === this may generate an error ${d:-`date`}
rbox 1000 s D3 | qhull C-0.01 Q5 FO Tcv
echo === this should generate an error ${d:-`date`}
rbox 1000 s D3 | qhull C-0.01 Q6 FO Po Tcv Qc
rbox 1000 s D3 | qhull C-0.01 Q7 FO Tcv Qc
rbox 1000 s D3 | qhull C-0.01 Qx Tcv Qc
echo === this may generate an error e.g., t1263080158 ${d:-`date`}
rbox 100 s D3 t | qhull R1e-3 Tcv Qc
rbox 100 s D3 t | qhull R1e-2 Tcv Qc
rbox 500 s D3 t | qhull R0.05 A-1 Tcv Qc
rbox 100 W0 D3 t | qhull R1e-3 Tcv Qc
rbox 100 W0 D3 t | qhull R1e-3 Qx Tcv Qc
rbox 100 W0 D3 t | qhull R1e-2 Tcv Qc
rbox 100 W0 D3 t | qhull R1e-2 Qx Tcv Qc
rbox 500 W0 D3 t | qhull R0.05 A-1 Tcv Qc
rbox 500 W0 D3 t | qhull R0.05 Qx Tcv Qc
rbox 1000 W1e-20 t | qhull Tcv Qc
rbox 1000 W1e-20 D4 t | qhull Tcv Qc
rbox 500 W1e-20 D5 t | qhull Tv Qc
rbox 100 W1e-20 D6 t | qhull Tv Qc
rbox 50 W1e-20 D6 t | qhull Qv Tv Qc
rbox 10000 D4 t | qhull QR0 Qc C-0.01 A0.3 Tv
rbox 1000 D2 t | qhull d QR0 Qc C-1e-8 Qu Tv
rbox 300 D5 t |qhull A-0.999 Qx Qc Tcv
rbox 100 D6 t |qhull A-0.9999 Qx Qc Tcv
rbox 50 D7 t |qhull A-0.99999 Qx Qc Tcv W0.1
echo === check bad cases for Qhull. May cause errors ${d:-`date`}
rbox 1000 L100000 s G1e-6 t | qhull Tv
rbox 1000 L100000 s G1e-6 t | qhull Tv Q10
rbox 1000 s Z1 G1e-13 t | qhull Tv
rbox 1000 s W1e-13 P0 t | qhull d Qbb Qc Tv
rbox 1000 s W1e-13 t | qhull d Tv
rbox 1000 s W1e-13 t D2 | qhull d Tv
echo =======================================================
echo =======================================================
echo === The following commands may cause errors ${d:-`date`}
echo =======================================================
echo =======================================================
rbox c D7 | qhull Q0 Tcv
rbox 100 s D3 | qhull Q0 E1e-3 Tc Po
rbox 100 s D3 | qhull Q0 E1e-2 Tc Po
rbox 100 s D3 | qhull Q0 E1e-1 Tc Po
rbox 100 s D3 | qhull Q0 R1e-3 Tc Po
rbox 100 s D3 | qhull Q0 R1e-2 Tc Po
rbox 100 s D3 | qhull Q0 R0.05 Tc
rbox 100 s D3 | qhull Q0 R0.05 Tc Po
rbox 1000 W1e-7 | qhull Q0 Tc Po
rbox 50 s | qhull Q0 V0.05 W0.01 Tc Po
rbox 100 s D5 | qhull Q0 R1e-2 Tc Po
qhull
qhull .
qhull -
rbox
cat html/qhull.txt html/rbox.txt
# end of q_test
diff --git a/eg/q_test-ok.txt b/eg/q_test-ok.txt
index c9024ea..eef8a7b 100644
--- a/eg/q_test-ok.txt
+++ b/eg/q_test-ok.txt
@@ -1,12266 +1,13021 @@
+============================================
+== make qtest ==============================
+============================================
+== Sun Aug 30 22:24:21 EDT 2015
+
+============================================
+== Test non-reentrant qset.c with mem.c ====
+============================================
+bin/testqset 10000
+
+
+Not testing qh_setduplicate and qh_setfree2.
+ These routines use heap-allocated set contents. See qhull tests.
+
+
+memory statistics:
+ 124 quick allocations
+ 25 short allocations
+ 8230 long allocations
+ 148 short frees
+ 8230 long frees
+ 24 bytes of short memory in use
+ 760 bytes of short memory in freelists
+ 130280 bytes of dropped short memory
+ 68 bytes of unused short memory (estimated)
+ 105548 bytes of long memory allocated (max, except for input)
+ 0 bytes of long memory in use (in 0 pieces)
+ 131064 bytes of short memory buffers (minus links)
+ 65536 bytes per short memory buffer (initially 131072 bytes)
+ 1135 calls to qh_setlarger
+5.6e+002 average copy size
+ freelists(bytes->count): 16->3 24->5 32->6 40->10
+
+
+testqset: OK
+
+qh_meminitbuffers: memory initialized with alignment 8
+SETelemsize is 4 bytes for pointer-to-int
+
+
+Testing qh_setappend 0..9999. Test i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i100 i1000 i9999
+
+Testing qh_settruncate 5000 and 0. Test n0
+
+Testing qh_setappend2ndlast 0,0..9999. Test 0 i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i100 i1000 i9999
+
+Testing SETtruncate_ 5000 and 0. Test n0
+
+Testing qh_setdelnthsorted and qh_setaddnth 1..9999. Test j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setappend_set 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setcompact and qh_setcopy 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_settemp* 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setdel*, qh_setaddsorted, and 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+============================================
+== Test reentrant qset_r.c with mem_r.c ====
+============================================
+bin/testqset_r 10000
+
+
+Not testing qh_setduplicate and qh_setfree2.
+ These routines use heap-allocated set contents. See qhull tests.
+
+memory statistics:
+ 124 quick allocations
+ 25 short allocations
+ 8230 long allocations
+ 148 short frees
+ 8230 long frees
+ 24 bytes of short memory in use
+ 760 bytes of short memory in freelists
+ 130280 bytes of dropped short memory
+ 68 bytes of unused short memory (estimated)
+ 105548 bytes of long memory allocated (max, except for input)
+ 0 bytes of long memory in use (in 0 pieces)
+ 131064 bytes of short memory buffers (minus links)
+ 65536 bytes per short memory buffer (initially 131072 bytes)
+ 1135 calls to qh_setlarger
+5.6e+002 average copy size
+ freelists(bytes->count): 16->3 24->5 32->6 40->10
+
+
+testqset_r: OK
+
+qh_meminitbuffers: memory initialized with alignment 8
+SETelemsize is 4 bytes for pointer-to-int
+
+
+Testing qh_setappend 0..9999. Test i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i100 i1000 i9999
+
+Testing qh_settruncate 5000 and 0. Test n0
+
+Testing qh_setappend2ndlast 0,0..9999. Test 0 i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i100 i1000 i9999
+
+Testing SETtruncate_ 5000 and 0. Test n0
+
+Testing qh_setdelnthsorted and qh_setaddnth 1..9999. Test j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setappend_set 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setcompact and qh_setcopy 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_settemp* 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+
+Testing qh_setdel*, qh_setaddsorted, and 0..9999. Test j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 j10 j100 j1000 j9999
+qh_memcheck: check size of freelists on qh->qhmem
+qh_memcheck: A segmentation fault indicates an overwrite of qh->qhmem
+qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree
+
+============================================
+== Run the qhull smoketest ====
+============================================
+bin/rbox D4 | bin/qhull Tv
+
+Starting the rbox smoketest for qhull. An immediate failure indicates
+that non-reentrant rbox was linked to reentrant routines. An immediate
+failure of qhull may indicate that qhull was linked to the wrong
+qhull library. Also try 'rbox D4 | qhull T1'
+
+Convex hull of 50 points in 4-d:
+
+ Number of vertices: 50
+ Number of facets: 260
+
+Statistics for: rbox D4 | qhull Tv
+
+ Number of points processed: 50
+ Number of hyperplanes created: 712
+ Number of distance tests for qhull: 1433
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 2.8e-015 of
+all facets. Will make 13000 distance computations.
+============================================
+== make test ===============================
+============================================
+
+==============================
+========= rbox/qhull =======
+==============================
+bin/rbox D4 | bin/qhull Tv
+
+Starting the rbox smoketest for qhull. An immediate failure indicates
+that non-reentrant rbox was linked to reentrant routines. An immediate
+failure of qhull may indicate that qhull was linked to the wrong
+qhull library. Also try 'rbox D4 | qhull T1'
+
+Convex hull of 50 points in 4-d:
+
+ Number of vertices: 50
+ Number of facets: 260
+
+Statistics for: rbox D4 | qhull Tv
+
+ Number of points processed: 50
+ Number of hyperplanes created: 712
+ Number of distance tests for qhull: 1433
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 2.8e-015 of
+all facets. Will make 13000 distance computations.
+
+==============================
+========= qconvex ============
+==============================
+bin/rbox 10 | bin/qconvex Tv
+
+Convex hull of 10 points in 3-d:
+
+ Number of vertices: 10
+ Number of facets: 16
+
+Statistics for: rbox 10 | qconvex Tv
+
+ Number of points processed: 10
+ Number of hyperplanes created: 27
+ Number of distance tests for qhull: 44
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 2e-015 of
+all facets. Will make 160 distance computations.
+
+==============================
+========= qdelaunay ==========
+==============================
+bin/rbox 10 | bin/qdelaunay Tv
+
+Delaunay triangulation by the convex hull of 10 points in 4-d:
+
+ Number of input sites: 10
+ Number of Delaunay regions: 15
+
+Statistics for: rbox 10 | qdelaunay Tv
+
+ Number of points processed: 10
+ Number of hyperplanes created: 48
+ Number of facets in hull: 25
+ Number of distance tests for qhull: 69
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 5.6e-015 of
+all facets. Will make 150 distance computations.
+
+==============================
+========= qhalf ==============
+==============================
+bin/rbox 10 | bin/qconvex FQ FV n Tv | bin/qhalf Tv
+
+Output completed. Verifying that all points are below 2e-015 of
+all facets. Will make 160 distance computations.
+
+Halfspace intersection by the convex hull of 16 points in 3-d:
+
+ Number of halfspaces: 16
+ Number of non-redundant halfspaces: 16
+ Number of intersection points: 10
+ Number of non-simplicial intersection points: 10
+
+Statistics for: rbox 10 | qconvex FQ FV n Tv | qhalf Tv
+
+ Number of points processed: 16
+ Number of hyperplanes created: 29
+ Number of distance tests for qhull: 100
+ Number of distance tests for merging: 342
+ Number of distance tests for checking: 156
+ Number of merged facets: 18
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 160 distance computations.
+
+==============================
+========= qvoronoi ===========
+==============================
+bin/rbox 10 | bin/qvoronoi Tv
+
+Voronoi diagram by the convex hull of 10 points in 4-d:
+
+ Number of Voronoi regions: 10
+ Number of Voronoi vertices: 15
+
+Statistics for: rbox 10 | qvoronoi Tv
+
+ Number of points processed: 10
+ Number of hyperplanes created: 48
+ Number of facets in hull: 25
+ Number of distance tests for qhull: 69
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 5.6e-015 of
+all facets. Will make 150 distance computations.
+
+==============================
+========= user_eg ============
+==============================
+bin/user_eg
+This is the output from user_eg_r.c
+
+It shows how qhull() may be called from an application using the qhull
+reentrant library. user_eg is not part of qhull itself. If it appears
+accidently, please remove user_eg_r.c from your project. If it fails
+immediately, user_eg_r.c was incorrectly linked to the non-reentrant library.
+Also try 'user_eg T1 2>&1'
+
+
+compute convex hull of cube after rotating input
+input
+ -1 -1 -1
+ 1 -1 -1
+ -1 1 -1
+ 1 1 -1
+ -1 -1 1
+ 1 -1 1
+ -1 1 1
+ 1 1 1
+
+8 vertices and 6 facets with normals:
+ -0 -0 -1
+ 0 -1 0
+ 1 -0 -0
+ -1 -0 -0
+ 0 1 -0
+ -0 -0 1
+
+compute 3-d Delaunay triangulation
+seed: 1440987863
+input
+ 0.406 -0.52 0.00249
+-0.0699 0.83 0.982
+ 0.969 0.252 -0.62
+ 0.366 -0.804 0.987
+-0.357 0.337 -0.529
+ 0.249 0.43 0.795
+-0.556 -1 -0.667
+-0.698 0.894 -0.61
+
+8 vertices and 18 facets with normals:
+ 0.18 0.066 -0.11 0.97
+ 0.62 -0.73 -0.26 0.056
+ 0.2 0.11 -0.074 0.97
+-0.045 0.046 0.02 1
+ -0.01 0.025 -1 -0.086
+ 0.19 -0.31 -0.84 -0.4
+ -0.91 -0.089 0.35 -0.2
+ -0.72 -0.33 0.44 -0.42
+ 0.89 -0.04 0.37 -0.26
+ 0.85 0.24 0.45 0.12
+ 0.5 0.48 -0.066 -0.72
+ -0.71 -0.3 0.46 -0.43
+ 0.29 0.9 -0.079 -0.32
+ 0.28 0.89 -0.096 -0.36
+ 0.14 0.9 -0.017 -0.4
+ -0.79 -0.23 0.47 -0.32
+ -0.79 -0.24 0.47 -0.33
+ -0.79 -0.23 0.47 -0.32
+
+find 3-d Delaunay triangle closest to [0.5, 0.5, ...]
+ 0.25 0.43 0.79
+-0.36 0.34 -0.53
+ 0.41 -0.52 0.00
+ 0.97 0.25 -0.62
+
+Compute a new triangulation as a separate instance of Qhull
+seed: 1440987864
+input
+ 0.406 -0.257 -0.486
+ 0.847 -0.105 -0.58
+-0.937 -0.39 0.739
+ 0.235 -0.0366 0.0257
+-0.695 0.406 -0.422
+-0.691 -0.227 0.81
+ 0.211 -0.866 0.168
+ 0.676 0.0723 -0.749
+
+8 vertices and 17 facets with normals:
+ -0.64 -0.51 -0.13 -0.55
+ 0.78 -0.43 0.08 -0.45
+ -0.52 -0.54 -0.37 -0.54
+ -0.17 -0.59 -0.57 0.54
+ -0.35 -0.56 -0.67 0.34
+-0.039 -0.7 -0.71 0.094
+ -0.34 -0.58 -0.73 0.16
+ 0.69 0.19 -0.34 -0.61
+ 0.038 0.45 -0.66 -0.6
+ -0.68 -0.41 -0.032 -0.61
+ 0.19 0.8 0.27 0.5
+ 0.29 0.86 0.41 0.099
+ 0.28 0.72 0.33 0.54
+ 0.36 0.81 0.46 0.11
+ 0.61 -0.045 0.63 0.48
+ -0.6 -0.53 0.019 -0.6
+ 0.66 0.16 0.74 0.054
+
+Free memory allocated by the new instance of Qhull, and redisplay the old results.
+
+
+
+8 vertices and 18 facets with normals:
+ 0.18 0.066 -0.11 0.97
+ 0.62 -0.73 -0.26 0.056
+ 0.2 0.11 -0.074 0.97
+-0.045 0.046 0.02 1
+ -0.01 0.025 -1 -0.086
+ 0.19 -0.31 -0.84 -0.4
+ -0.91 -0.089 0.35 -0.2
+ -0.72 -0.33 0.44 -0.42
+ 0.89 -0.04 0.37 -0.26
+ 0.85 0.24 0.45 0.12
+ 0.5 0.48 -0.066 -0.72
+ -0.71 -0.3 0.46 -0.43
+ 0.29 0.9 -0.079 -0.32
+ 0.28 0.89 -0.096 -0.36
+ 0.14 0.9 -0.017 -0.4
+ -0.79 -0.23 0.47 -0.32
+ -0.79 -0.24 0.47 -0.33
+ -0.79 -0.23 0.47 -0.32
+
+compute halfspace intersection about the origin for a diamond
+input as halfspace coefficients + offsets
+ -1 -1 -1 -1
+ 1 -1 -1 -1
+ -1 1 -1 -1
+ 1 1 -1 -1
+ -1 -1 1 -1
+ 1 -1 1 -1
+ -1 1 1 -1
+ 1 1 1 -1
+3
+6
+ 0 0 -1
+ 0 -1 0
+ 1 0 0
+ -1 0 0
+ 0 1 0
+ 0 0 1
+
+8 vertices and 6 facets with normals:
+ -0 -0 -1
+ 0 -1 0
+ 1 -0 -0
+ -1 -0 -0
+ 0 1 -0
+ -0 -0 1
+
+Convex hull of 8 points in 3-d:
+
+ Number of vertices: 8
+ Number of facets: 6
+ Number of non-simplicial facets: 6
+
+Statistics for: | qhull s Tcv
+
+ Number of points processed: 8
+ Number of hyperplanes created: 11
+ Number of distance tests for qhull: 35
+ Number of distance tests for merging: 142
+ Number of distance tests for checking: 56
+ Number of merged facets: 6
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 48 distance computations.
+
+Delaunay triangulation by the convex hull of 8 points in 4-d:
+
+ Number of input sites: 8
+ Number of Delaunay regions: 13
+
+Statistics for: | qhull s d Tcv
+
+ Number of points processed: 8
+ Number of hyperplanes created: 30
+ Number of facets in hull: 18
+ Number of distance tests for qhull: 33
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 1.1e-014 of
+all facets. Will make 104 distance computations.
+
+Delaunay triangulation by the convex hull of 8 points in 4-d:
+
+ Number of input sites: 8
+ Number of Delaunay regions: 7
+
+Statistics for: | qhull s d Tcv
+
+ Number of points processed: 8
+ Number of hyperplanes created: 26
+ Number of facets in hull: 17
+ Number of distance tests for qhull: 29
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 9.5e-015 of
+all facets. Will make 56 distance computations.
+
+Halfspace intersection by the convex hull of 8 points in 3-d:
+
+ Number of halfspaces: 8
+ Number of non-redundant halfspaces: 8
+ Number of intersection points: 6
+ Number of non-simplicial intersection points: 6
+
+Statistics for: | qhull H0 s Tcv Fp
+
+ Number of points processed: 8
+ Number of hyperplanes created: 11
+ Number of distance tests for qhull: 35
+ Number of distance tests for merging: 142
+ Number of distance tests for checking: 56
+ Number of merged facets: 6
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 48 distance computations.
+
+==============================
+========= user_eg2 ===========
+==============================
+bin/user_eg2
+This is the output from user_eg2_r.c
+
+It shows how qhull() may be called from an application using qhull's
+static, reentrant library. user_eg2 is not part of qhull itself. If it
+appears accidently, please remove user_eg2_r.c from your project. If it fails
+immediately, user_eg2_r.c was incorrectly linked to the non-reentrant library.
+Also try 'user_eg2 T1 2>&1'
+
+
+compute triangulated convex hull of cube after rotating input
+
+8 vertices and 12 facets with normals:
+ -0 -0 -1
+ -0 -0 -1
+ 0 -1 0
+ 0 -1 0
+ 1 -0 -0
+ 1 -0 -0
+ -1 -0 -0
+ -1 -0 -0
+ 0 1 -0
+ 0 1 -0
+ -0 -0 1
+ -0 -0 1
+
+add points in a diamond
+9 vertices and 14 facets
+10 vertices and 16 facets
+11 vertices and 16 facets
+12 vertices and 16 facets
+13 vertices and 14 facets
+14 vertices and 12 facets
+
+14 vertices and 12 facets with normals:
+ 0.71 -0.71 -0
+ -0.71 -0.71 0
+ -0.71 0.71 -0
+ 0.71 0.71 -0
+ -0.71 -0 -0.71
+ -0 0.71 -0.71
+ 0 -0.71 -0.71
+ 0.71 0 -0.71
+ -0 -0.71 0.71
+ -0.71 0 0.71
+ 0.71 0 0.71
+ -0 0.71 0.71
+
+compute 2-d Delaunay triangulation
+seed: 1440987863
+
+8 vertices and 12 facets with normals:
+ 0.72 -0.016 -0.69
+-0.018 -0.63 0.78
+ 0.13 -0.65 0.75
+ 0.011 0.91 -0.42
+ 0.44 0.64 -0.63
+ 0.37 0.69 -0.62
+ -0.61 -0.73 0.31
+ -0.44 0.75 -0.5
+ -0.52 0.035 -0.85
+ -0.61 0.48 -0.63
+ -0.6 -0.76 -0.23
+ -0.64 -0.75 0.17
+
+add points to triangulation
+added point p8: -1 -0.7369 1.543
+9 points, 0 extra points, 9 vertices, and 14 facets in total
+added point p9: 0.5112 -0.0827 0.2682
+10 points, 0 extra points, 10 vertices, and 16 facets in total
+added point p10: 0.06553 -0.5621 0.3202
+11 points, 0 extra points, 11 vertices, and 18 facets in total
+added point p11: -0.9059 0.3577 0.9486
+12 points, 0 extra points, 12 vertices, and 20 facets in total
+added point p12: 0.3586 0.8694 0.8844
+13 points, 0 extra points, 13 vertices, and 22 facets in total
+added point p13: -0.233 0.03883 0.0558
+14 points, 0 extra points, 14 vertices, and 24 facets in total
+
+find Delaunay triangle closest to [0.5, 0.5, ...]
+ 0.36 0.87
+ 0.51 -0.08
+ 0.00 -0.07
+
+compute halfspace intersection about the origin for a diamond
+
+add halfspaces for cube to intersection
+added offset -1 and normal 1.732 0 0
+8 points, 1 extra points, 9 vertices, and 9 facets in total
+added offset -1 and normal -1.732 0 0
+8 points, 2 extra points, 10 vertices, and 12 facets in total
+added offset -1 and normal 0 1.732 0
+8 points, 3 extra points, 11 vertices, and 15 facets in total
+added offset -1 and normal 0 -1.732 0
+8 points, 4 extra points, 12 vertices, and 18 facets in total
+added offset -1 and normal 0 0 1.732
+8 points, 5 extra points, 13 vertices, and 21 facets in total
+added offset -1 and normal 0 0 -1.732
+8 points, 6 extra points, 14 vertices, and 24 facets in total
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 96 distance computations.
+
+Convex hull of 14 points in 3-d:
+
+ Number of vertices: 14
+ Number of facets: 12
+ Number of non-simplicial facets: 12
+
+Statistics for: user_eg cube | qhull s Tcv Q11
+
+ Number of points processed: 14
+ Number of hyperplanes created: 23
+ Number of distance tests for qhull: 65
+ Number of distance tests for merging: 450
+ Number of distance tests for checking: 190
+ Number of merged facets: 18
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 168 distance computations.
+
+Delaunay triangulation by the convex hull of 8 points in 3-d:
+
+ Number of input sites: 8
+ Number of Delaunay regions: 8
+
+Statistics for: user_eg Delaunay | qhull s d Tcv
+
+ Number of points processed: 8
+ Number of hyperplanes created: 22
+ Number of facets in hull: 12
+ Number of distance tests for qhull: 35
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 6.9e-015 of
+all facets. Will make 64 distance computations.
+
+Delaunay triangulation by the convex hull of 14 points in 3-d:
+
+ Number of input sites: 14
+ Number of Delaunay regions: 20
+
+Statistics for: user_eg Delaunay | qhull s d Tcv
+
+ Number of points processed: 14
+ Number of hyperplanes created: 52
+ Number of facets in hull: 24
+ Number of distance tests for qhull: 76
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below 6.9e-015 of
+all facets. Will make 280 distance computations.
+
+Halfspace intersection by the convex hull of 8 points in 3-d:
+
+ Number of halfspaces: 8
+ Number of non-redundant halfspaces: 8
+ Number of intersection points: 6
+ Number of non-simplicial intersection points: 6
+
+Statistics for: user_eg halfspaces | qhull H0 s Tcv
+
+ Number of points processed: 8
+ Number of hyperplanes created: 11
+ Number of distance tests for qhull: 35
+ Number of distance tests for merging: 142
+ Number of distance tests for checking: 56
+ Number of merged facets: 6
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 48 distance computations.
+
+Halfspace intersection by the convex hull of 14 points in 3-d:
+
+ Number of halfspaces: 14
+ Number of non-redundant halfspaces: 14
+ Number of intersection points: 24
+
+Statistics for: user_eg halfspaces | qhull H0 s Tcv
+
+ Number of points processed: 14
+ Number of hyperplanes created: 35
+ Number of distance tests for qhull: 59
+ Number of distance tests for merging: 306
+ Number of distance tests for checking: 214
+ Number of merged facets: 6
+ CPU seconds to compute hull (after input): 0
+
+
+Output completed. Verifying that all points are below outer planes of
+all facets. Will make 192 distance computations.
+
+==============================
+========= user_eg3 ===========
+==============================
+bin/user_eg3 rbox "10 D2" "2 D2" qhull "s p" facets
+rbox 10 D2
+rbox 2 D2
+
+Results of s p
+
+Convex hull of 12 points in 2-d:
+
+ Number of vertices: 5
+ Number of facets: 5
+
+Statistics for: rbox "10 D2" "2 D2" | qhull s p
+
+ Number of points processed: 5
+ Number of hyperplanes created: 8
+ Number of distance tests for qhull: 64
+ CPU seconds to compute hull (after input): 0
+
+2
+5
+-0.02222276248244826 -0.4979727817680433
+-0.4285431913366012 0.4745826469497594
+0.3790312361708201 0.3779794437605696
+0.3443122672329771 -0.1437312230875075
+-0.3674659290047977 0.0001301793382784133
+
+Facets created by Qhull::runQhull()
+- f1
+ - flags: top simplicial
+ - normal: 0.118775 0.992921
+ - offset: -0.420323
+ - vertices: p4(v1) p1(v0)
+ - neighboring facets: f6 f4
+- f4
+ - flags: top simplicial
+ - normal: 0.997793 -0.0664014
+ - offset: -0.353096
+ - vertices: p8(v4) p4(v1)
+ - neighboring facets: f1 f5
+- f5
+ - flags: bottom simplicial
+ - normal: 0.694945 -0.719063
+ - offset: -0.34263
+ - vertices: p8(v4) p0(v2)
+ - neighboring facets: f7 f4
+- f6
+ - flags: bottom simplicial
+ - normal: -0.991816 -0.127679
+ - offset: -0.364442
+ - vertices: p10(v5) p1(v0)
+ - neighboring facets: f1 f7
+- f7
+ - flags: top simplicial
+ - normal: -0.821881 -0.569659
+ - offset: -0.301939
+ - vertices: p10(v5) p0(v2)
+ - neighboring facets: f5 f6
+============================================
+== make testall ============================
+============================================
+== Sun Aug 30 22:24:23 EDT 2015
+
eg/q_eg
+==============================
+========= eg/q_eg ============
+== Create geomview examples ==
+==============================
+
rbox c D3 | qconvex s G >eg/eg.01.cube
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 D3 | qconvex s G
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 84
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
rbox c d G2.0 | qconvex s G >eg/eg.02.diamond.cube
Convex hull of 14 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox c d G2.0 | qconvex s G
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 88
Number of distance tests for merging: 45
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
rbox s 100 D3 | qconvex s G >eg/eg.03.sphere
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox s 100 D3 | qconvex s G
Number of points processed: 100
Number of hyperplanes created: 503
Number of distance tests for qhull: 1631
CPU seconds to compute hull (after input): 0
rbox s 100 D2 | qconvex s G >eg/eg.04.circle
Convex hull of 100 points in 2-d:
Number of vertices: 100
Number of facets: 100
Statistics for: rbox s 100 D2 | qconvex s G
Number of points processed: 100
Number of hyperplanes created: 198
Number of distance tests for qhull: 891
CPU seconds to compute hull (after input): 0
rbox 10 l | qconvex s G >eg/eg.05.spiral
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 l | qconvex s G
Number of points processed: 10
Number of hyperplanes created: 26
Number of distance tests for qhull: 40
CPU seconds to compute hull (after input): 0
rbox 1000 D2 | qconvex s C-0.03 Qc Gapcv >eg/eg.06.merge.square
Convex hull of 1000 points in 2-d:
Number of vertices: 4
Number of coplanar points: 103
Number of facets: 4
Statistics for: rbox 1000 D2 | qconvex s C-0.03 Qc Gapcv
Number of points processed: 6
Number of hyperplanes created: 8
Number of distance tests for qhull: 12111
Number of distance tests for merging: 43
Number of distance tests for checking: 3736
Number of merged facets: 2
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.019 (0.3x)
Maximum distance of vertex below facet: -0.019 (0.3x)
rbox 1000 D3 | qconvex s G >eg/eg.07.box
Convex hull of 1000 points in 3-d:
Number of vertices: 73
Number of facets: 142
Statistics for: rbox 1000 D3 | qconvex s G
Number of points processed: 81
Number of hyperplanes created: 368
Number of distance tests for qhull: 12884
CPU seconds to compute hull (after input): 0
rbox c G0.4 s 500 | qconvex s G >eg/eg.08a.cube.sphere
Convex hull of 508 points in 3-d:
Number of vertices: 63
Number of facets: 122
Statistics for: rbox c G0.4 s 500 | qconvex s G
Number of points processed: 99
Number of hyperplanes created: 443
Number of distance tests for qhull: 9648
CPU seconds to compute hull (after input): 0
rbox d G0.6 s 500 | qconvex s G >eg/eg.08b.diamond.sphere
Convex hull of 506 points in 3-d:
Number of vertices: 397
Number of facets: 790
Statistics for: rbox d G0.6 s 500 | qconvex s G
Number of points processed: 409
Number of hyperplanes created: 2032
Number of distance tests for qhull: 10055
Number of distance tests for merging: 8153
Number of distance tests for checking: 10136
Number of merged facets: 1
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
rbox 100 L3 G0.5 s | qconvex s G >eg/eg.09.lens
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 L3 G0.5 s | qconvex s G
Number of points processed: 100
Number of hyperplanes created: 483
Number of distance tests for qhull: 1642
CPU seconds to compute hull (after input): 0
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG0 >eg/eg.10a.sphere.visible
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Number of 'good' facets: 44
Statistics for: rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG0
Number of points processed: 100
Number of hyperplanes created: 513
Number of distance tests for qhull: 1704
CPU seconds to compute hull (after input): 0
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG-0 >eg/eg.10b.sphere.beyond
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Number of 'good' facets: 152
Statistics for: rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG-0
Number of points processed: 100
Number of hyperplanes created: 513
Number of distance tests for qhull: 1704
CPU seconds to compute hull (after input): 0
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG0 PG >eg/eg.10c.sphere.horizon
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Number of 'good' facets: 44
Statistics for: rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QG0 PG
Number of points processed: 100
Number of hyperplanes created: 513
Number of distance tests for qhull: 1704
CPU seconds to compute hull (after input): 0
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QV0 PgG >eg/eg.10d.sphere.cone
Convex hull of 101 points in 3-d:
Number of vertices: 85
Number of facets: 166
Number of 'good' facets: 14
Statistics for: rbox 100 s P0.5,0.5,0.5 | qconvex s Ga QV0 PgG
Number of points processed: 88
Number of hyperplanes created: 429
Number of distance tests for qhull: 1594
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
rbox 100 s P0.5,0.5,0.5 | qconvex s Ga >eg/eg.10e.sphere.new
Convex hull of 101 points in 3-d:
Number of vertices: 85
Number of facets: 166
Statistics for: rbox 100 s P0.5,0.5,0.5 | qconvex s Ga
Number of points processed: 88
Number of hyperplanes created: 429
Number of distance tests for qhull: 1594
CPU seconds to compute hull (after input): 0
rbox 100 s P0.5,0.5,0.5 | qhull s Ga QV0g Q0 >eg/eg.14.sphere.corner
Convex hull of 101 points in 3-d:
Number of vertices: 42
Number of facets: 80
Number of 'good' facets: 14
Statistics for: rbox 100 s P0.5,0.5,0.5 | qhull s Ga QV0g Q0
Number of points processed: 45
Number of hyperplanes created: 194
Number of distance tests for qhull: 1435
CPU seconds to compute hull (after input): 0
rbox 500 W0 | qconvex s QR0 Qc Gvp >eg/eg.15a.surface
Convex hull of 500 points in 3-d:
Number of vertices: 66
Number of coplanar points: 434
Number of facets: 80
Number of non-simplicial facets: 6
-Statistics for: rbox 500 W0 | qconvex s QR0 Qc Gvp QR1327454200
+Statistics for: rbox 500 W0 | qconvex s QR0 Qc Gvp QR1440987864
- Number of points processed: 70
- Number of hyperplanes created: 211
- Number of distance tests for qhull: 8277
- Number of distance tests for merging: 1884
+ Number of points processed: 71
+ Number of hyperplanes created: 205
+ Number of distance tests for qhull: 7468
+ Number of distance tests for merging: 1877
Number of distance tests for checking: 6765
- Number of merged facets: 56
+ Number of merged facets: 58
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 2.3e-015 (0.3x)
rbox 500 W0 | qconvex s QR0 Qt Qc Gvp >eg/eg.15b.triangle
Convex hull of 500 points in 3-d:
Number of vertices: 66
Number of coplanar points: 434
Number of facets: 128
Number of triangulated facets: 6
-Statistics for: rbox 500 W0 | qconvex s QR0 Qt Qc Gvp QR1327454200
+Statistics for: rbox 500 W0 | qconvex s QR0 Qt Qc Gvp QR1440987864
- Number of points processed: 70
- Number of hyperplanes created: 211
- Number of distance tests for qhull: 8277
- Number of distance tests for merging: 1950
+ Number of points processed: 71
+ Number of hyperplanes created: 205
+ Number of distance tests for qhull: 7468
+ Number of distance tests for merging: 1943
Number of distance tests for checking: 6765
- Number of merged facets: 56
+ Number of merged facets: 58
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 2.3e-015 (0.3x)
rbox 500 W0 | qconvex s QR0 QJ5e-2 Qc Gvp >eg/eg.15c.joggle
Convex hull of 500 points in 3-d:
- Number of vertices: 78
- Number of coplanar points: 422
- Number of facets: 152
+ Number of vertices: 69
+ Number of coplanar points: 431
+ Number of facets: 134
-Statistics for: rbox 500 W0 | qconvex s QR0 QJ5e-2 Qc Gvp QR1327454200
+Statistics for: rbox 500 W0 | qconvex s QR0 QJ5e-2 Qc Gvp QR1440987864
- Number of points processed: 89
- Number of hyperplanes created: 423
- Number of distance tests for qhull: 20845
- CPU seconds to compute hull (after input): 0.015
+ Number of points processed: 82
+ Number of hyperplanes created: 343
+ Number of distance tests for qhull: 16483
+ CPU seconds to compute hull (after input): 0
Input joggled by: 0.05
echo 2 = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 >eg/eg.data.17
echo 25 >>eg/eg.data.17
rbox 15 D2 B0.3 W0.25 c G0.5 | tail -n +3 >>eg/eg.data.17
rbox 6 r s D2 B0.2 | tail -n +3 >>eg/eg.data.17
qdelaunay s Qt <eg/eg.data.17 GnraD2 >eg/eg.17a.delaunay.2
Delaunay triangulation by the convex hull of 25 points in 3-d:
Number of input sites: 25
Number of Delaunay regions: 44
Number of triangulated facets: 1
Statistics for: = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 | qdelaunay s Qt GnraD2
Number of points processed: 25
Number of hyperplanes created: 90
Number of facets in hull: 46
Number of distance tests for qhull: 289
Number of distance tests for merging: 492
Number of distance tests for checking: 307
Number of merged facets: 4
CPU seconds to compute hull (after input): 0
qdelaunay s <eg/eg.data.17 GnraD2 >eg/eg.17b.delaunay.2i
Delaunay triangulation by the convex hull of 25 points in 3-d:
Number of input sites: 25
Number of Delaunay regions: 41
Number of non-simplicial Delaunay regions: 1
Statistics for: = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 | qdelaunay s GnraD2
Number of points processed: 25
Number of hyperplanes created: 90
Number of facets in hull: 42
Number of distance tests for qhull: 289
Number of distance tests for merging: 482
Number of distance tests for checking: 307
Number of merged facets: 4
CPU seconds to compute hull (after input): 0
qdelaunay s <eg/eg.data.17 C-0 Ga >eg/eg.17c.delaunay.2-3
Delaunay triangulation by the convex hull of 25 points in 3-d:
Number of input sites: 25
Number of Delaunay regions: 0
Number of non-simplicial Delaunay regions: 2
Statistics for: = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 | qdelaunay s C-0 Ga
Number of points processed: 25
Number of hyperplanes created: 90
Number of facets in hull: 42
Number of distance tests for qhull: 289
Number of distance tests for merging: 482
Number of distance tests for checking: 307
Number of merged facets: 4
CPU seconds to compute hull (after input): 0
qvoronoi s QJ <eg/eg.data.17 Gna >eg/eg.17d.voronoi.2
Voronoi diagram by the convex hull of 25 points in 3-d:
Number of Voronoi regions: 25
Number of Voronoi vertices: 44
Statistics for: = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 | qvoronoi s QJ Gna
Number of points processed: 25
Number of hyperplanes created: 99
Number of facets in hull: 46
Number of distance tests for qhull: 283
CPU seconds to compute hull (after input): 0
Input joggled by: 4.2e-011
qvoronoi s <eg/eg.data.17 Gna >eg/eg.17e.voronoi.2i
Voronoi diagram by the convex hull of 25 points in 3-d:
Number of Voronoi regions: 25
Number of Voronoi vertices: 41
Number of non-simplicial Voronoi vertices: 1
Statistics for: = rbox 6 r s D2, rbox 15 B0.3 W0.25, c G0.5 | qvoronoi s Gna
Number of points processed: 25
Number of hyperplanes created: 90
Number of facets in hull: 42
Number of distance tests for qhull: 289
Number of distance tests for merging: 482
Number of distance tests for checking: 307
Number of merged facets: 4
CPU seconds to compute hull (after input): 0
rbox c G0.1 d | qdelaunay Gt Qz >eg/eg.17f.delaunay.3
rbox 10 D2 d | qdelaunay s Qu G >eg/eg.18a.furthest.2-3
Furthest-site Delaunay triangulation by the convex hull of 14 points in 3-d:
Number of input sites: 14
Number of Delaunay regions: 0
Statistics for: rbox 10 D2 d | qdelaunay s Qu G
Number of points processed: 14
Number of hyperplanes created: 46
Number of facets in hull: 24
Number of distance tests for qhull: 85
Number of distance tests for merging: 213
Number of distance tests for checking: 304
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
rbox 10 D2 d | qdelaunay s Qu Pd2 G >eg/eg.18b.furthest-up.2-3
Furthest-site Delaunay triangulation by the convex hull of 14 points in 3-d:
Number of input sites: 14
Number of Delaunay regions: 7
Statistics for: rbox 10 D2 d | qdelaunay s Qu Pd2 G
Number of points processed: 14
Number of hyperplanes created: 46
Number of facets in hull: 24
Number of distance tests for qhull: 85
Number of distance tests for merging: 213
Number of distance tests for checking: 304
Number of merged facets: 1
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
rbox 10 D2 d | qvoronoi s Qu Gv >eg/eg.18c.furthest.2
Furthest-site Voronoi vertices by the convex hull of 14 points in 3-d:
Number of Voronoi regions: 14
Number of Voronoi vertices: 7
Statistics for: rbox 10 D2 d | qvoronoi s Qu Gv
Number of points processed: 14
Number of hyperplanes created: 46
Number of facets in hull: 24
Number of distance tests for qhull: 85
Number of distance tests for merging: 213
Number of distance tests for checking: 304
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
rbox 10 D3 | qvoronoi s FQ QV5 p | qconvex s G >eg/eg.19.voronoi.region.3
Voronoi diagram by the convex hull of 10 points in 4-d:
Number of Voronoi regions: 10
Number of 'good' Voronoi vertices: 10
Statistics for: rbox 10 D3 | qvoronoi s FQ QV5 p
Number of points processed: 10
Number of hyperplanes created: 44
Number of facets in hull: 27
Number of distance tests for qhull: 67
CPU seconds to compute hull (after input): 0
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 9
Number of non-simplicial facets: 5
Statistics for: rbox 10 D3 | qvoronoi s FQ QV5 p | qconvex s G
Number of points processed: 10
Number of hyperplanes created: 18
Number of distance tests for qhull: 45
Number of distance tests for merging: 130
Number of distance tests for checking: 89
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
rbox r s 20 Z1 G0.2 | qconvex s QR1 G >eg/eg.20.cone
Convex hull of 41 points in 3-d:
Number of vertices: 41
Number of facets: 41
Number of non-simplicial facets: 21
Statistics for: rbox r s 20 Z1 G0.2 | qconvex s QR1 G QR1
Number of points processed: 41
Number of hyperplanes created: 115
Number of distance tests for qhull: 624
Number of distance tests for merging: 1584
Number of distance tests for checking: 721
Number of merged facets: 61
CPU seconds to compute hull (after input): 0
rbox 200 s | qconvex s Qc R0.014 Gpav >eg/eg.21b.roundoff.fixed
Convex hull of 200 points in 3-d:
Number of vertices: 65
Number of coplanar points: 135
Number of facets: 52
Number of non-simplicial facets: 43
Statistics for: rbox 200 s | qconvex s Qc R0.014 Gpav
Number of points processed: 73
Number of hyperplanes created: 291
Number of distance tests for qhull: 9744
Number of distance tests for merging: 4407
Number of distance tests for checking: 4026
Number of merged facets: 176
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.048 (0.9x)
Maximum distance of vertex below facet: -0.098 (1.7x)
rbox 1000 s| qconvex s C0.01 Qc Gcrp >eg/eg.22a.merge.sphere.01
Convex hull of 1000 points in 3-d:
Number of vertices: 223
Number of coplanar points: 777
Number of facets: 117
Number of non-simplicial facets: 117
Statistics for: rbox 1000 s | qconvex s C0.01 Qc Gcrp
Number of points processed: 1000
Number of hyperplanes created: 5545
Number of distance tests for qhull: 121035
Number of distance tests for merging: 79123
Number of distance tests for checking: 8141
Number of merged facets: 1879
- CPU seconds to compute hull (after input): 0.016
+ CPU seconds to compute hull (after input): 0.015
Maximum distance of vertex below facet: -0.04 (1.3x)
rbox 1000 s| qconvex s C-0.01 Qc Gcrp >eg/eg.22b.merge.sphere.-01
Convex hull of 1000 points in 3-d:
Number of vertices: 102
Number of coplanar points: 898
Number of facets: 103
Number of non-simplicial facets: 75
Statistics for: rbox 1000 s | qconvex s C-0.01 Qc Gcrp
Number of points processed: 108
Number of hyperplanes created: 467
Number of distance tests for qhull: 71156
Number of distance tests for merging: 6748
Number of distance tests for checking: 31209
Number of merged facets: 256
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.031 (1.0x)
Maximum distance of vertex below facet: -0.065 (2.2x)
rbox 1000 s| qconvex s C0.05 Qc Gcrpv >eg/eg.22c.merge.sphere.05
Convex hull of 1000 points in 3-d:
Number of vertices: 48
Number of coplanar points: 952
Number of facets: 26
Number of non-simplicial facets: 26
Statistics for: rbox 1000 s | qconvex s C0.05 Qc Gcrpv
Number of points processed: 1000
Number of hyperplanes created: 5545
Number of distance tests for qhull: 55658
Number of distance tests for merging: 83457
Number of distance tests for checking: 7742
Number of merged facets: 1970
CPU seconds to compute hull (after input): 0.015
Maximum distance of vertex below facet: -0.21 (1.4x)
rbox 1000 s| qconvex s C-0.05 Qc Gcrpv >eg/eg.22d.merge.sphere.-05
Convex hull of 1000 points in 3-d:
Number of vertices: 18
Number of coplanar points: 982
Number of facets: 15
Number of non-simplicial facets: 13
Statistics for: rbox 1000 s | qconvex s C-0.05 Qc Gcrpv
Number of points processed: 22
Number of hyperplanes created: 69
Number of distance tests for qhull: 44445
Number of distance tests for merging: 1034
Number of distance tests for checking: 13690
Number of merged facets: 41
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.14 (0.9x)
Maximum distance of vertex below facet: -0.15 (1.0x)
rbox 1000 | qconvex s Gcprvah C0.1 Qc >eg/eg.23.merge.cube
Convex hull of 1000 points in 3-d:
Number of vertices: 8
Number of coplanar points: 741
Number of facets: 6
Number of non-simplicial facets: 6
Statistics for: rbox 1000 | qconvex s Gcprvah C0.1 Qc
Number of points processed: 95
Number of hyperplanes created: 453
Number of distance tests for qhull: 60073
Number of distance tests for merging: 5413
Number of distance tests for checking: 6014
Number of merged facets: 146
CPU seconds to compute hull (after input): 0
Maximum distance of vertex below facet: -0.18 (0.6x)
rbox 5000 D4 | qconvex s GD0v Pd0:0.5 C-0.02 C0.1 >eg/eg.24.merge.cube.4d-in-3d
Convex hull of 5000 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of 'good' facets: 1
Number of 'good' non-simplicial facets: 1
Statistics for: rbox 5000 D4 | qconvex s GD0v Pd0:0.5 C-0.02 C0.1
Number of points processed: 30
Number of hyperplanes created: 182
Number of distance tests for qhull: 658286
Number of distance tests for merging: 4770
Number of distance tests for checking: 45000
Number of merged facets: 188
CPU seconds to compute hull (after input): 0.031
Maximum distance of point above facet: 0.14 (0.4x)
Maximum distance of vertex below facet: -0.31 (0.8x)
rbox 5000 D4 | qconvex s s C-0.02 C0.1 Gh >eg/eg.30.4d.merge.cube
Convex hull of 5000 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of non-simplicial facets: 8
Statistics for: rbox 5000 D4 | qconvex s s C-0.02 C0.1 Gh
Number of points processed: 30
Number of hyperplanes created: 182
Number of distance tests for qhull: 658286
Number of distance tests for merging: 4770
Number of distance tests for checking: 45000
Number of merged facets: 188
- CPU seconds to compute hull (after input): 0.032
+ CPU seconds to compute hull (after input): 0.031
Maximum distance of point above facet: 0.14 (0.4x)
Maximum distance of vertex below facet: -0.31 (0.8x)
rbox 20 D3 | qdelaunay s G >eg/eg.31.4d.delaunay
Delaunay triangulation by the convex hull of 20 points in 4-d:
Number of input sites: 20
Number of Delaunay regions: 0
Statistics for: rbox 20 D3 | qdelaunay s G
Number of points processed: 20
Number of hyperplanes created: 162
Number of facets in hull: 81
Number of distance tests for qhull: 302
CPU seconds to compute hull (after input): 0
rbox 30 s D4 | qconvex s G Pd0d1d2D3 >eg/eg.32.4d.octant
Convex hull of 30 points in 4-d:
Number of vertices: 30
Number of facets: 138
Number of 'good' facets: 9
Statistics for: rbox 30 s D4 | qconvex s G Pd0d1d2D3
Number of points processed: 30
Number of hyperplanes created: 340
Number of distance tests for qhull: 650
CPU seconds to compute hull (after input): 0
rbox 10 r s Z1 G0.3 | qconvex G >eg/eg.33a.cone
rbox 10 r s Z1 G0.3 | qconvex FQ FV n | qhalf G >eg/eg.33b.cone.dual
rbox 10 r s Z1 G0.3 | qconvex FQ FV n | qhalf FQ s Fp | qconvex G >eg/eg.33c.cone.halfspace
Halfspace intersection by the convex hull of 21 points in 3-d:
Number of halfspaces: 21
Number of non-redundant halfspaces: 21
Number of intersection points: 21
Number of non-simplicial intersection points: 11
Statistics for: rbox 10 r s Z1 G0.3 | qconvex FQ FV n | qhalf FQ s Fp
Number of points processed: 21
Number of hyperplanes created: 48
Number of distance tests for qhull: 162
Number of distance tests for merging: 435
Number of distance tests for checking: 261
Number of merged facets: 18
CPU seconds to compute hull (after input): 0
echo ==the following should generate flipped and concave facets== >/dev/null
rbox 200 s | qhull Q0 s R0.014 Gav Po >eg/eg.21a.roundoff.errors
QH6136 qhull precision error: facet f506 is flipped, distance= 0.461556194655
QH6136 qhull precision error: facet f592 is flipped, distance= 0.439612545215
QH6136 qhull precision error: facet f604 is flipped, distance= 0.465768128315
QH6136 qhull precision error: facet f506 is flipped, distance= 0.468691154013
QH6136 qhull precision error: facet f592 is flipped, distance= 0.450451888758
QH6136 qhull precision error: facet f604 is flipped, distance= 0.471152553888
QH6115 qhull precision error: f127 is concave to f267, since p65(v17) is 0.02603 above
QH6115 qhull precision error: f139 is concave to f285, since p13(v34) is 0.02883 above
QH6115 qhull precision error: f166 is concave to f316, since p189(v18) is 0.008704 above
QH6115 qhull precision error: f198 is concave to f604, since p109(v11) is 0.02657 above
QH6115 qhull precision error: f242 is concave to f527, since p65(v17) is 0.02938 above
QH6115 qhull precision error: f259 is concave to f462, since p59(v60) is 0.008633 above
QH6115 qhull precision error: f280 is concave to f286, since p22(v65) is 0.01973 above
QH6115 qhull precision error: f288 is concave to f310, since p71(v67) is 0.02406 above
QH6115 qhull precision error: f297 is concave to f487, since p180(v38) is 0.008078 above
QH6115 qhull precision error: f313 is concave to f496, since p63(v41) is 0.03309 above
QH6115 qhull precision error: f330 is concave to f331, since p10(v64) is 0.02231 above
QH6115 qhull precision error: f397 is concave to f542, since p69(v51) is 0.01923 above
QH6115 qhull precision error: f399 is concave to f543, since p155(v31) is 0.01245 above
QH6115 qhull precision error: f417 is concave to f552, since p184(v71) is 0.009005 above
QH6115 qhull precision error: f426 is concave to f477, since p135(v95) is 0.016 above
QH6115 qhull precision error: f431 is concave to f555, since p135(v95) is 0.008306 above
QH6115 qhull precision error: f442 is concave to f559, since p97(v98) is 0.04007 above
QH6115 qhull precision error: f444 is concave to f245, since p194(v99) is 0.0124 above
QH6115 qhull precision error: f457 is concave to f505, since p70(v101) is 0.05613 above
QH6115 qhull precision error: f460 is concave to f565, since p176(v61) is 0.02392 above
QH6115 qhull precision error: f469 is concave to f580, since p119(v9) is 0.07256 above
QH6115 qhull precision error: f472 is concave to f582, since p138(v63) is 0.04511 above
QH6115 qhull precision error: f481 is concave to f624, since p79(v93) is 0.0132 above
QH6115 qhull precision error: f484 is concave to f483, since p79(v93) is 0.01528 above
QH6115 qhull precision error: f492 is concave to f551, since p163(v108) is 0.05382 above
QH6115 qhull precision error: f501 is concave to f602, since p29(v10) is 0.01867 above
QH6115 qhull precision error: f505 is concave to f457, since p128(v110) is 0.008966 above
QH6113 qhull precision error: f506 is flipped(interior point is outside)
QH6115 qhull precision error: f520 is concave to f541, since p100(v114) is 0.009004 above
QH6115 qhull precision error: f521 is concave to f516, since p100(v114) is 0.01561 above
QH6115 qhull precision error: f522 is concave to f526, since p100(v114) is 0.0118 above
QH6115 qhull precision error: f534 is concave to f535, since p190(v2) is 0.01582 above
QH6115 qhull precision error: f535 is concave to f534, since p154(v47) is 0.009917 above
QH6115 qhull precision error: f544 is concave to f620, since p58(v91) is 0.01945 above
QH6115 qhull precision error: f551 is concave to f492, since p41(v120) is 0.0114 above
QH6115 qhull precision error: f559 is concave to f442, since p38(v122) is 0.01392 above
QH6115 qhull precision error: f565 is concave to f460, since p73(v123) is 0.01004 above
QH6115 qhull precision error: f566 is concave to f571, since p133(v16) is 0.01303 above
QH6115 qhull precision error: f580 is concave to f469, since p158(v127) is 0.0104 above
QH6113 qhull precision error: f592 is flipped(interior point is outside)
QH6115 qhull precision error: f595 is concave to f626, since p22(v65) is 0.008193 above
QH6115 qhull precision error: f603 is concave to f500, since p14(v132) is 0.00736 above
QH6113 qhull precision error: f604 is flipped(interior point is outside)
QH6115 qhull precision error: f619 is concave to f617, since p12(v1) is 0.007428 above
Convex hull of 200 points in 3-d:
Number of vertices: 138
Number of facets: 272
Statistics for: rbox 200 s | qhull Q0 s R0.014 Gav Po
Number of points processed: 138
Number of hyperplanes created: 629
Number of distance tests for qhull: 4659
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
120 coplanar half ridges in output
41 concave half ridges in output
3 flipped facets
125 coplanar horizon facets for new vertices
62 coplanar points during partitioning
echo ==the preceeding should report flipped and concave facets== >/dev/null
eg/q_egtest
+==============================
+========= eg/q_egtest ========
+== Create geomview tests =====
+==============================
+
rbox d D3 | qconvex s Gnrv Tc Tv >eg/eg.t01.spheres.3
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qconvex s Gnrv Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox d D2 | qconvex s Gnv Tc Tv >eg/eg.t02.spheres.2
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox d D2 | qconvex s Gnv Tc Tv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 4
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 16 distance computations.
rbox d D3 | qconvex s Gnrp Tc Tv >eg/eg.t03.points.3
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qconvex s Gnrp Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox d D2 | qconvex s Gnp Tc Tv >eg/eg.t04.points.2
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox d D2 | qconvex s Gnp Tc Tv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 4
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 16 distance computations.
rbox c D4 | qconvex s C0.05 GnpcD3 Pd3:0.5 Tc Tv >eg/eg.t05.centrum.points.4-3
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of 'good' facets: 1
Number of 'good' non-simplicial facets: 1
Statistics for: rbox c D4 | qconvex s C0.05 GnpcD3 Pd3:0.5 Tc Tv
Number of points processed: 16
Number of hyperplanes created: 26
Number of distance tests for qhull: 168
Number of distance tests for merging: 963
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 16 distance computations.
rbox d D3 | qconvex s Gnrc Tc Tv >eg/eg.t06.centrums.3.precise
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qconvex s Gnrc Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox d D3 | qconvex s C0.05 Gnrc Tc Tv >eg/eg.t07.centrums.3
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qconvex s C0.05 Gnrc Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 169
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox d D2 | qconvex s C0.05 Gc Tc Tv >eg/eg.t08.centrums.2
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox d D2 | qconvex s C0.05 Gc Tc Tv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 4
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 16 distance computations.
rbox d D3 | qconvex s Gnha Tc Tv >eg/eg.t09.intersect.3
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qconvex s Gnha Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox d D3 | qconvex s GaD0 Pd0 Tc Tv >eg/eg.t10.faces.3-2
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Number of 'good' facets: 4
Statistics for: rbox d D3 | qconvex s GaD0 Pd0 Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 24 distance computations.
rbox d D3 | qconvex s GnrpD0 Pd0 Tc Tv >eg/eg.t11.points.3-2
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Number of 'good' facets: 4
Statistics for: rbox d D3 | qconvex s GnrpD0 Pd0 Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 24 distance computations.
rbox d D3 | qconvex s C0.05 GnrcD0 Pd0 Tc Tv >eg/eg.t12.centrums.3-2
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Number of 'good' facets: 4
Statistics for: rbox d D3 | qconvex s C0.05 GnrcD0 Pd0 Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 169
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 24 distance computations.
rbox d D3 | qconvex s GnhaD0 Pd0 Tc Tv >eg/eg.t13.intersect.3-2
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Number of 'good' facets: 4
Statistics for: rbox d D3 | qconvex s GnhaD0 Pd0 Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 24 distance computations.
rbox d D3 | qconvex s GnrvD0 Pd0 Tc Tv >eg/eg.t14.spheres.3-2
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Number of 'good' facets: 4
Statistics for: rbox d D3 | qconvex s GnrvD0 Pd0 Tc Tv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 24 distance computations.
rbox c D4 | qconvex s GvD0 Pd0:0.5 Tc Tv >eg/eg.t15.spheres.4-3
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of 'good' facets: 1
Number of 'good' non-simplicial facets: 1
Statistics for: rbox c D4 | qconvex s GvD0 Pd0:0.5 Tc Tv
Number of points processed: 16
Number of hyperplanes created: 26
Number of distance tests for qhull: 168
Number of distance tests for merging: 788
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 16 distance computations.
rbox c D4 | qhull s Q0 C0 GpD0 Pd0:0.5 Tc Tv >eg/eg.t16.points.4-3
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of 'good' facets: 1
Number of 'good' non-simplicial facets: 1
Statistics for: rbox c D4 | qhull s Q0 C0 GpD0 Pd0:0.5 Tc Tv
Number of points processed: 16
Number of hyperplanes created: 62
Number of distance tests for qhull: 163
Number of distance tests for merging: 1304
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 16 distance computations.
rbox c D4 | qconvex s GahD0 Pd0:0.5 Tc Tv >eg/eg.t17.intersect.4-3
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of 'good' facets: 1
Number of 'good' non-simplicial facets: 1
Statistics for: rbox c D4 | qconvex s GahD0 Pd0:0.5 Tc Tv
Number of points processed: 16
Number of hyperplanes created: 26
Number of distance tests for qhull: 168
Number of distance tests for merging: 788
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 16 distance computations.
rbox 100 s | qconvex s C-0.05 Qc Gicvprh Tc Tv >eg/eg.t18.imprecise.3
Convex hull of 100 points in 3-d:
Number of vertices: 18
Number of coplanar points: 82
Number of facets: 16
Number of non-simplicial facets: 12
Statistics for: rbox 100 s | qconvex s C-0.05 Qc Gicvprh Tc Tv
Number of points processed: 18
Number of hyperplanes created: 60
Number of distance tests for qhull: 3313
Number of distance tests for merging: 1030
Number of distance tests for checking: 1347
Number of merged facets: 29
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.092 (0.6x)
Maximum distance of vertex below facet: -0.14 (0.9x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1600 distance computations.
rbox 30 s D4 | qconvex s GhD0 Pd0d1d2D3 Tc >eg/eg.t19.intersect.precise.4-3
Convex hull of 30 points in 4-d:
Number of vertices: 30
Number of facets: 138
Number of 'good' facets: 9
Statistics for: rbox 30 s D4 | qconvex s GhD0 Pd0d1d2D3 Tc
Number of points processed: 30
Number of hyperplanes created: 340
Number of distance tests for qhull: 650
CPU seconds to compute hull (after input): 0
rbox 100 s P1,1,1 | qconvex s QG-0 Pgp Tc G >eg/eg.t20.notvisible
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Number of 'good' facets: 125
Statistics for: rbox 100 s P1,1,1 | qconvex s QG-0 Pgp Tc G
Number of points processed: 100
Number of hyperplanes created: 503
Number of distance tests for qhull: 1631
CPU seconds to compute hull (after input): 0
rbox 100 s | qconvex s QV-10 Pgp Tc G >eg/eg.t21.notvertex
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Number of 'good' facets: 191
Statistics for: rbox 100 s | qconvex s QV-10 Pgp Tc G
Number of points processed: 100
Number of hyperplanes created: 494
Number of distance tests for qhull: 1641
CPU seconds to compute hull (after input): 0
rbox 100 r D2 P1,1 | qhull s Pd0:0.7 PD0:0.8 QgG0 G Tv >eg/eg.t22.split
Convex hull of 100 points in 2-d:
Number of vertices: 42
Number of facets: 42
Number of 'good' facets: 3
Statistics for: rbox 100 r D2 P1,1 | qhull s Pd0:0.7 PD0:0.8 QgG0 G Tv
Number of points processed: 89
Number of hyperplanes created: 176
Number of distance tests for qhull: 1099
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.6e-015 of
all good facets. Will make 303 distance computations.
rbox 100 D2 c G1.0 | qvoronoi s A-0.95 Gna Tv >eg/eg.t23.voronoi.imprecise
Voronoi diagram by the convex hull of 104 points in 3-d:
Number of Voronoi regions: 13
Total number of nearly incident points: 91
Number of Voronoi vertices: 13
Number of non-simplicial Voronoi vertices: 5
Statistics for: rbox 100 D2 c G1.0 | qvoronoi s A-0.95 Gna Tv
Number of points processed: 13
Number of hyperplanes created: 39
Number of facets in hull: 14
Number of distance tests for qhull: 2740
Number of distance tests for merging: 464
Number of distance tests for checking: 1119
Number of merged facets: 13
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.098 (0.1x)
Maximum distance of vertex below facet: -0.082 (0.1x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1352 distance computations.
rbox 30 s D4 | qconvex s Gh Pd0d1d2D3 Tc >eg/eg.t24.intersect.precise.4d
Convex hull of 30 points in 4-d:
Number of vertices: 30
Number of facets: 138
Number of 'good' facets: 9
Statistics for: rbox 30 s D4 | qconvex s Gh Pd0d1d2D3 Tc
Number of points processed: 30
Number of hyperplanes created: 340
Number of distance tests for qhull: 650
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
echo ==the following generates an error== >/dev/null
rbox 1000 D4 | qhull Q0 s Po R0.005 Ga Tc Tv >eg/eg.t25.neighbors.4d
QH6136 qhull precision error: facet f491 is flipped, distance= 0.413460414284
QH6136 qhull precision error: facet f949 is flipped, distance= 0.558894018107
QH6107 qhull precision error: facets f977, f981 and f978 meet at a ridge with more than 2 neighbors. Can not continue.
ERRONEOUS FACET:
- f977
- flags: bottom simplicial new
- normal: -0.07131 -0.04413 0.08982 -0.9924
- offset: -0.5084414
- vertices: p108(v73) p722(v63) p713(v35) p241(v7)
- neighboring facets: f824 f968 f971 f978
ERRONEOUS OTHER FACET:
- f981
- flags: top simplicial new
- normal: -0.005308 -0.0126 0.005272 -0.9999
- offset: -0.4947257
- vertices: p108(v73) p722(v63) p713(v35) p62(v20)
- neighboring facets: f825
ERRONEOUS and NEIGHBORING FACETS to output
While executing: rbox 1000 D4 | qhull Q0 s Po R0.005 Ga Tc Tv
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315164332 Q0-no-premerge summary Poutput-forced
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1509976643 Q0-no-premerge summary Poutput-forced
Random_perturb 0.005 Gall-points Tcheck-frequently Tverify _max-width 1
Error-roundoff 0.0025 Visible-distance 0.0025 U-coplanar-distance 0.0025
Width-outside 0.005 _wide-facet 0.015
Last point added to hull was p108.
Convex hull of 1000 points in 4-d:
Number of vertices: 68
Number of facets: 346
Statistics for: rbox 1000 D4 | qhull Q0 s Po R0.005 Ga Tc Tv
Number of points processed: 73
Number of hyperplanes created: 986
Number of distance tests for qhull: 28532
precision problems (corrected unless 'Q0' or an error)
2 flipped facets
42 coplanar horizon facets for new vertices
141 coplanar points during partitioning
9 degenerate hyperplanes recomputed with gaussian elimination
9 nearly singular or axis-parallel hyperplanes
Precision problems were detected during construction of the convex hull.
This occurs because convex hull algorithms assume that calculations are
exact, but floating-point arithmetic has roundoff errors.
To correct for precision problems, do not use 'Q0'. By default, Qhull
selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',
Qhull joggles the input to prevent precision problems. See "Imprecision
in Qhull" (qh-impre.htm).
If you use 'Q0', the output may include
coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,
Qhull may produce a ridge with four neighbors or two facets with the same
vertices. Qhull reports these events when they occur. It stops when a
concave ridge, flipped facet, or duplicate facet occurs.
If you need triangular output:
- use option 'Qt' to triangulate the output
- use option 'QJ' to joggle the input points and remove precision errors
- use option 'Ft'. It triangulates non-simplicial facets with added points.
If you must use 'Q0',
try one or more of the following options. They can not guarantee an output.
- use 'QbB' to scale the input to a cube.
- use 'Po' to produce output and prevent partitioning for flipped facets
- use 'V0' to set min. distance to visible facet as 0 instead of roundoff
- use 'En' to specify a maximum roundoff error less than 0.0025.
- options 'Qf', 'Qbb', and 'QR0' may also help
To guarantee simplicial output:
- use option 'Qt' to triangulate the output
- use option 'QJ' to joggle the input points and remove precision errors
- use option 'Ft' to triangulate the output by adding points
- use exact arithmetic (see "Imprecision in Qhull", qh-impre.htm)
echo ==the previous should generate an error== >/dev/null
eg/q_test
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 6
Number of non-simplicial facets: 6
Statistics for: | qhull s Tcv
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 142
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
Delaunay triangulation by the convex hull of 8 points in 4-d:
Number of input sites: 8
- Number of Delaunay regions: 11
+ Number of Delaunay regions: 12
Statistics for: | qhull s d Tcv
Number of points processed: 8
- Number of hyperplanes created: 28
- Number of facets in hull: 16
- Number of distance tests for qhull: 33
+ Number of hyperplanes created: 26
+ Number of facets in hull: 17
+ Number of distance tests for qhull: 31
CPU seconds to compute hull (after input): 0
-Output completed. Verifying that all points are below 1.4e-014 of
-all facets. Will make 88 distance computations.
+Output completed. Verifying that all points are below 8.8e-015 of
+all facets. Will make 96 distance computations.
Delaunay triangulation by the convex hull of 8 points in 4-d:
Number of input sites: 8
- Number of Delaunay regions: 11
+ Number of Delaunay regions: 8
Statistics for: | qhull s d Tcv
Number of points processed: 8
- Number of hyperplanes created: 24
- Number of facets in hull: 17
- Number of distance tests for qhull: 31
+ Number of hyperplanes created: 26
+ Number of facets in hull: 16
+ Number of distance tests for qhull: 30
CPU seconds to compute hull (after input): 0
-Output completed. Verifying that all points are below 7.3e-015 of
-all facets. Will make 88 distance computations.
+Output completed. Verifying that all points are below 9.2e-015 of
+all facets. Will make 64 distance computations.
Halfspace intersection by the convex hull of 8 points in 3-d:
Number of halfspaces: 8
Number of non-redundant halfspaces: 8
Number of intersection points: 6
Number of non-simplicial intersection points: 6
Statistics for: | qhull H0 s Tcv Fp
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 142
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
-echo === errors if 'user_eg' and 'user_eg2' not found ===
-=== errors if user_eg and user_eg2 not found ===
-echo === check user_eg ${d:-`date`} =====================
-date
-=== check user_eg Tue Jan 24 20:16:42 EST 2012 =====================
+==============================
+========= eg/q_test ==========
+== Check qhull programs ======
+==============================
+
+==============================
+== check user_eg, user_eg2, and user_eg3
+== errors if user_eg and user_eg2 not found
+==============================
user_eg "QR1 p n Qt" "v p" Fp
-This is the output from user_eg.c
+This is the output from user_eg_r.c
It shows how qhull() may be called from an application using the qhull
-shared library. It is not part of qhull itself. If it appears accidently,
-please remove user_eg.c from your project.
+reentrant library. user_eg is not part of qhull itself. If it appears
+accidently, please remove user_eg_r.c from your project. If it fails
+immediately, user_eg_r.c was incorrectly linked to the non-reentrant library.
+Also try 'user_eg T1 2>&1'
compute convex hull of cube after rotating input
input
-1 -1 -1
1 -1 -1
-1 1 -1
1 1 -1
-1 -1 1
1 -1 1
-1 1 1
1 1 1
3
8
0.9124763375291641 1.390833937612012 -0.4826674750136243
-0.5764091147442416 0.565375258822974 -1.532352227508615
-0.1847368907548403 1.250953879569599 1.183632828365285
-1.673622343028246 0.4254952007805605 0.1339480758702939
1.673622343028246 -0.4254952007805605 -0.1339480758702939
0.1847368907548403 -1.250953879569599 -1.183632828365285
0.5764091147442416 -0.565375258822974 1.532352227508615
-0.9124763375291641 -1.390833937612012 0.4826674750136243
4
12
-0.380573002749541 0.9081645691962865 -0.1743596995716652 -1
-0.380573002749541 0.9081645691962865 -0.1743596995716652 -1
0.744442726136703 0.4127293393945193 0.5248423762474955 -1
0.744442726136703 0.4127293393945193 0.5248423762474955 -1
-0.5486066141420022 -0.06994002902120672 0.8331501516894545 -1
-0.5486066141420022 -0.06994002902120672 0.8331501516894545 -1
0.5486066141420022 0.06994002902120679 -0.8331501516894545 -1
0.5486066141420022 0.06994002902120679 -0.8331501516894545 -1
0.380573002749541 -0.9081645691962865 0.1743596995716652 -1
0.380573002749541 -0.9081645691962865 0.1743596995716652 -1
-0.7444427261367029 -0.4127293393945193 -0.5248423762474955 -0.9999999999999997
-0.7444427261367029 -0.4127293393945193 -0.5248423762474955 -0.9999999999999997
8 vertices and 12 facets with normals:
-0.38 0.91 -0.17
-0.38 0.91 -0.17
0.74 0.41 0.52
0.74 0.41 0.52
-0.55 -0.07 0.83
-0.55 -0.07 0.83
0.55 0.07 -0.83
0.55 0.07 -0.83
0.38 -0.91 0.17
0.38 -0.91 0.17
-0.74 -0.41 -0.52
-0.74 -0.41 -0.52
compute 3-d Delaunay triangulation
-seed: 1327454202
+seed: 1440987866
input
--0.706 0.185 -0.997
- 0.739 0.981 0.915
--0.0492 0.993 -0.337
--0.408 -0.521 0.378
--0.174 -0.217 -0.829
--0.114 -0.874 0.268
- 0.414 -0.87 -0.86
- 0.684 -0.12 0.241
+ 0.406 0.27 0.536
+ 0.682 0.0266 0.296
+-0.749 0.326 -0.544
+-0.0257 -0.503 0.103
+ 0.629 0.544 -0.209
+-0.572 0.457 0.841
+-0.255 -0.599 -0.162
+-0.577 0.428 0.973
3
-11
-8.817140186696875 3.450584294550091 -5.020639188104951
-0.5403564279616564 -0.6912825989872701 2.425011907306929
--0.1199937357891065 0.4735709729694704 0.5770495599647179
-3.100407885814694 2.400973701393672 -6.350407240410952
-1.236411828590869 0.4751228563895312 -1.138297941446634
--0.5020263900519639 0.2374638672802573 -0.1134692063160839
--0.08697626605473376 0.1691016807526869 -0.05020263571440065
--2.27154828024003 -2.667494449872159 -1.43761610758808
--1.575536916403145 -1.453895924539648 -0.7477231573352229
-0.2382928326855393 -0.4652796623935117 -0.2533544020986503
-0.06787343520023301 -0.2808240579638571 -0.1335157472366256
+12
+2.053681319994957 -5.24211287660431 7.604814278383908
+-0.006501077629782914 0.1139128707586965 -0.3864075936086688
+0.9277292902776515 -0.6305926068475578 -0.9244539158640872
+-0.1075705695805811 0.2704028159634234 -0.07336122915888735
+0.120058589613817 0.1332722142389445 -0.05590509783105876
+-0.2816403644805237 0.2636746338386882 0.1123952339801021
+-0.157946867978552 -0.1819940540817634 0.7840937639775835
+-2.657590129722368 -0.9228659139754254 0.5276635516441215
+-0.6204676998466154 0.01978519728108497 0.1787229023101261
+-0.9534938681352754 -0.5498292234062085 0.6732778134631337
+-0.2109442321566642 0.7166552049091644 0.06028811160515268
+1.107937576733393 4.616125305687903 1.89216188550534
-8 vertices and 16 facets with normals:
- -0.51 -0.42 0.26 0.7
- 0.65 -0.6 0.43 0.18
- 0.43 0.42 -0.68 0.42
- 0.82 0.32 -0.47 -0.047
- -0.68 -0.27 0.39 0.55
- -0.82 0.37 0.43 0.092
- 0.21 -0.26 0.92 -0.19
- -0.13 0.52 0.64 -0.55
- 0.41 0.32 -0.85 -0.067
- 0.68 0.26 -0.63 -0.28
- -0.66 0.31 -0.15 -0.66
- -0.16 0.31 -0.093 -0.93
- -0.59 -0.7 -0.38 -0.13
- -0.68 -0.63 -0.32 -0.22
- 0.31 -0.61 -0.33 -0.65
- 0.11 -0.47 -0.23 -0.84
+8 vertices and 17 facets with normals:
+ 0.28 -0.76 0.36 0.46
+ 0.22 -0.55 0.8 -0.053
+ 0.27 -0.42 -0.27 0.82
+ 0.32 -0.46 -0.21 0.8
+ -0.01 0.18 -0.6 -0.78
+ 0.6 -0.41 -0.6 -0.33
+ 0.68 0.37 0.46 0.44
+ -0.18 0.46 -0.13 -0.86
+ 0.22 0.25 -0.1 -0.94
+ -0.44 0.41 0.18 -0.78
+ -0.16 -0.19 0.82 -0.52
+ -0.91 -0.32 0.18 -0.17
+ -0.76 0.024 0.22 -0.61
+ -0.69 -0.4 0.49 -0.36
+-0.091 0.97 -0.12 0.2
+ -0.23 0.8 0.067 -0.55
+ 0.22 0.9 0.37 -0.097
find 3-d Delaunay triangle closest to [0.5, 0.5, ...]
--0.41 -0.52 0.38
--0.05 0.99 -0.34
- 0.68 -0.12 0.24
- 0.74 0.98 0.92
+-0.57 0.46 0.84
+ 0.63 0.54 -0.21
+ 0.41 0.27 0.54
+-0.58 0.43 0.97
-save first triangulation and compute a new triangulation
-seed: 1327454203
+Compute a new triangulation as a separate instance of Qhull
+seed: 1440987867
input
--0.706 0.448 0.514
--0.343 0.047 -0.647
-0.0449 0.351 -0.979
--0.538 0.246 -0.583
--0.512 -0.147 -0.722
- 0.945 0.468 0.283
--0.819 -0.736 -0.0249
-0.0573 -0.942 0.102
+ 0.406 0.533 0.0473
+-0.401 -0.908 0.734
+-0.655 -0.317 0.815
+-0.156 0.264 -0.858
+ 0.291 0.613 -0.102
+ 0.487 -0.2 0.856
+ 0.511 -0.465 0.673
+ 0.796 -0.394 0.834
3
-11
--0.2386622335477796 -0.1566542442491845 0.1628208587902705
-0.09843684708370071 0.01493208449583039 0.2089868348364177
-0.5723090085175291 -0.2124517280896852 -0.3449177752423304
--0.4619263792107396 -0.09379720018847126 0.07126402711263546
-0.03918182679269278 1.273584146776618 -0.1032761907666938
-0.07192003860173046 0.4326707178511331 0.0563639535749717
-0.1540676134834845 0.5692882636221464 -0.119465246220046
--0.2503820888867752 -0.4059765127196031 -0.1601524894225976
-0.4530074947629944 -0.7123718802783976 -0.9412410897971241
--0.5748832691392634 -0.1527250737689812 -0.08932774746840733
--0.5344126046033305 0.2483559898669195 -1.217616521674434
-
-8 vertices and 17 facets with normals:
- -0.14 0.22 -0.0066 0.97
- 0.033 -0.24 0.78 0.57
- -0.4 -0.26 0.27 -0.84
- 0.18 0.027 0.38 -0.91
- 0.27 -0.32 -0.24 0.87
- 0.66 -0.25 -0.4 -0.58
- -0.67 0.33 -0.31 0.59
- -0.67 -0.14 0.1 -0.72
- 0.029 0.93 -0.075 -0.36
- 0.11 0.65 0.084 -0.75
- 0.2 0.73 -0.15 -0.64
- 0.073 -0.63 -0.7 0.34
- -0.35 -0.57 -0.23 -0.7
- 0.33 -0.52 -0.69 -0.37
- -0.69 0.26 -0.41 0.54
- -0.73 -0.2 -0.11 -0.64
- -0.37 0.17 -0.84 -0.35
-
-save second triangulation and restore first one
+8
+-0.1629567956697229 -0.3421584605019314 -0.05921764327058199
+-0.2007388173033371 -0.2067349252599354 -0.02341738782188189
+-0.1514977855616732 -0.2770548829315278 -0.03318320469334592
+1.773845693020259 -0.7385305196404486 -1.093163979795168
+-0.06653098220926657 -0.4199650131652234 0.8151930624738309
+0.2690370397819248 -0.9913001275806789 1.684094669464881
+-0.08398952045958485 -0.06272870473781025 0.2974411154245948
+0.8023063276207141 0.0250404372545173 0.2884908994046808
8 vertices and 16 facets with normals:
- -0.51 -0.42 0.26 0.7
- 0.65 -0.6 0.43 0.18
- 0.43 0.42 -0.68 0.42
- 0.82 0.32 -0.47 -0.047
- -0.68 -0.27 0.39 0.55
- -0.82 0.37 0.43 0.092
- 0.21 -0.26 0.92 -0.19
- -0.13 0.52 0.64 -0.55
- 0.41 0.32 -0.85 -0.067
- 0.68 0.26 -0.63 -0.28
- -0.66 0.31 -0.15 -0.66
- -0.16 0.31 -0.093 -0.93
- -0.59 -0.7 -0.38 -0.13
- -0.68 -0.63 -0.32 -0.22
- 0.31 -0.61 -0.33 -0.65
- 0.11 -0.47 -0.23 -0.84
-
-free first triangulation and restore second one.
+ -0.1 0.71 0.065 0.7
+ -0.15 0.44 -0.083 0.88
+ -0.26 -0.54 -0.094 -0.79
+ 0.37 -0.76 -0.53 0.06
+ -0.35 -0.36 -0.041 -0.87
+ -0.26 -0.47 -0.056 -0.84
+ 0.81 0.24 -0.47 0.26
+ 0.78 -0.33 -0.48 -0.22
+-0.021 -0.14 0.99 0.0033
+-0.064 -0.4 0.78 -0.48
+ 0.13 -0.49 0.83 -0.25
+ -0.14 -0.11 0.5 -0.85
+ 0.81 0.025 0.29 -0.51
+-0.039 0.8 0.47 0.37
+-0.051 0.8 0.51 0.31
+-0.0022 0.8 0.48 0.35
+
+Free memory allocated by the new instance of Qhull, and redisplay the old results.
+
+
8 vertices and 17 facets with normals:
- -0.14 0.22 -0.0066 0.97
- 0.033 -0.24 0.78 0.57
- -0.4 -0.26 0.27 -0.84
- 0.18 0.027 0.38 -0.91
- 0.27 -0.32 -0.24 0.87
- 0.66 -0.25 -0.4 -0.58
- -0.67 0.33 -0.31 0.59
- -0.67 -0.14 0.1 -0.72
- 0.029 0.93 -0.075 -0.36
- 0.11 0.65 0.084 -0.75
- 0.2 0.73 -0.15 -0.64
- 0.073 -0.63 -0.7 0.34
- -0.35 -0.57 -0.23 -0.7
- 0.33 -0.52 -0.69 -0.37
- -0.69 0.26 -0.41 0.54
- -0.73 -0.2 -0.11 -0.64
- -0.37 0.17 -0.84 -0.35
+ 0.28 -0.76 0.36 0.46
+ 0.22 -0.55 0.8 -0.053
+ 0.27 -0.42 -0.27 0.82
+ 0.32 -0.46 -0.21 0.8
+ -0.01 0.18 -0.6 -0.78
+ 0.6 -0.41 -0.6 -0.33
+ 0.68 0.37 0.46 0.44
+ -0.18 0.46 -0.13 -0.86
+ 0.22 0.25 -0.1 -0.94
+ -0.44 0.41 0.18 -0.78
+ -0.16 -0.19 0.82 -0.52
+ -0.91 -0.32 0.18 -0.17
+ -0.76 0.024 0.22 -0.61
+ -0.69 -0.4 0.49 -0.36
+-0.091 0.97 -0.12 0.2
+ -0.23 0.8 0.067 -0.55
+ 0.22 0.9 0.37 -0.097
compute halfspace intersection about the origin for a diamond
input as halfspace coefficients + offsets
-1 -1 -1 -1
1 -1 -1 -1
-1 1 -1 -1
1 1 -1 -1
-1 -1 1 -1
1 -1 1 -1
-1 1 1 -1
1 1 1 -1
3
6
0 0 -1
0 -1 0
1 0 0
-1 0 0
0 1 0
0 0 1
8 vertices and 6 facets with normals:
-0 -0 -1
0 -1 0
1 -0 -0
-1 -0 -0
0 1 -0
-0 -0 1
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 12
Number of triangulated facets: 6
Statistics for: | qhull s Tcv QR1 p n Qt QR1
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 24
Number of distance tests for merging: 186
Number of distance tests for checking: 56
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96 distance computations.
Voronoi diagram by the convex hull of 8 points in 4-d:
Number of Voronoi regions: 8
- Number of Voronoi vertices: 11
+ Number of Voronoi vertices: 12
Statistics for: | qhull s d Tcv v p
Number of points processed: 8
- Number of hyperplanes created: 28
- Number of facets in hull: 16
- Number of distance tests for qhull: 33
+ Number of hyperplanes created: 26
+ Number of facets in hull: 17
+ Number of distance tests for qhull: 31
CPU seconds to compute hull (after input): 0
-Output completed. Verifying that all points are below 1.4e-014 of
-all facets. Will make 88 distance computations.
+Output completed. Verifying that all points are below 8.8e-015 of
+all facets. Will make 96 distance computations.
Voronoi diagram by the convex hull of 8 points in 4-d:
Number of Voronoi regions: 8
- Number of Voronoi vertices: 11
+ Number of Voronoi vertices: 8
Statistics for: | qhull s d Tcv v p
Number of points processed: 8
- Number of hyperplanes created: 24
- Number of facets in hull: 17
- Number of distance tests for qhull: 31
+ Number of hyperplanes created: 26
+ Number of facets in hull: 16
+ Number of distance tests for qhull: 30
CPU seconds to compute hull (after input): 0
-Output completed. Verifying that all points are below 7.3e-015 of
-all facets. Will make 88 distance computations.
+Output completed. Verifying that all points are below 9.2e-015 of
+all facets. Will make 64 distance computations.
Halfspace intersection by the convex hull of 8 points in 3-d:
Number of halfspaces: 8
Number of non-redundant halfspaces: 8
Number of intersection points: 6
Number of non-simplicial intersection points: 6
Statistics for: | qhull H0 s Tcv Fp
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 142
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
user_eg2 "QR1 p" "v p" Fp
-This is the output from user_eg2.c
+This is the output from user_eg2_r.c
-It shows how qhull() may be called from an application in the same way as
-qconvex. It is not part of qhull itself. If it appears accidently,
-please remove user_eg2.c from your project.
+It shows how qhull() may be called from an application using qhull's
+static, reentrant library. user_eg2 is not part of qhull itself. If it
+appears accidently, please remove user_eg2_r.c from your project. If it fails
+immediately, user_eg2_r.c was incorrectly linked to the non-reentrant library.
+Also try 'user_eg2 T1 2>&1'
compute triangulated convex hull of cube after rotating input
8 vertices and 12 facets with normals:
-0.38 0.91 -0.17
-0.38 0.91 -0.17
0.74 0.41 0.52
0.74 0.41 0.52
-0.55 -0.07 0.83
-0.55 -0.07 0.83
0.55 0.07 -0.83
0.55 0.07 -0.83
0.38 -0.91 0.17
0.38 -0.91 0.17
-0.74 -0.41 -0.52
-0.74 -0.41 -0.52
add points in a diamond
9 vertices and 14 facets
10 vertices and 16 facets
11 vertices and 18 facets
12 vertices and 20 facets
13 vertices and 22 facets
14 vertices and 24 facets
14 vertices and 24 facets with normals:
-0.67 0.63 -0.39
0.67 -0.63 0.39
-0.1 -0.71 0.7
0.65 -0.66 0.37
0.63 -0.7 -0.34
-0.65 -0.65 -0.41
-0.62 -0.62 -0.49
-0.65 0.66 -0.37
-0.63 0.7 0.34
0.1 0.71 -0.7
0.65 0.65 0.41
0.62 0.62 0.49
-0.7 -0.13 -0.7
-0.62 -0.49 -0.62
0.11 0.7 -0.71
0.68 0.29 -0.68
0.66 -0.34 -0.67
0.67 -0.3 -0.67
-0.66 0.34 0.67
-0.67 0.3 0.67
0.7 0.13 0.7
0.62 0.49 0.62
-0.11 -0.7 0.71
-0.68 -0.29 0.68
3
14
0.9124763375291641 1.390833937612012 -0.4826674750136243
-0.5764091147442416 0.565375258822974 -1.532352227508615
-0.1847368907548403 1.250953879569599 1.183632828365285
-1.673622343028246 0.4254952007805605 0.1339480758702939
1.673622343028246 -0.4254952007805605 -0.1339480758702939
0.1847368907548403 -1.250953879569599 -1.183632828365285
0.5764091147442416 -0.565375258822974 1.532352227508615
-0.9124763375291641 -1.390833937612012 0.4826674750136243
-2 0 0
2 0 0
0 -2 0
0 2 0
0 0 -2
0 0 2
compute 2-d Delaunay triangulation
-seed: 1327454202
+seed: 1440987866
8 vertices and 12 facets with normals:
- -0.12 0.96 0.24
- -0.46 0.77 -0.44
- -0.03 -0.7 0.71
- 0.065 -0.78 0.62
- 0.21 0.57 -0.79
- 0.73 -0.68 -0.046
- 0.57 0.46 -0.68
- -0.69 -0.15 -0.7
- -0.61 0.095 -0.79
- -0.69 -0.11 -0.71
- -0.76 0.45 -0.47
- -0.92 0.17 -0.36
+ -0.85 -0.52 0.023
+ -0.2 -0.25 -0.95
+ 0.02 -0.3 0.95
+ 0.1 -0.34 0.93
+ -0.23 0.91 -0.35
+ 0.8 -0.59 -0.036
+ 0.32 -0.37 -0.87
+ 0.5 0.61 -0.61
+ 0.3 0.71 -0.64
+ -0.44 0.64 -0.62
+ -0.82 0.12 -0.56
+ -0.26 -0.16 -0.95
2
9
--0.5240618706046448 0.8690922898675285
-0.1358064000046035 0.3626730983099605
-7.974840388221374 -7.374405564218564
-0.4195468496642627 0.3335095202541082
--0.4922740987263012 -0.1088952709353415
--0.3827738348641049 0.0600803560653607
--0.4876069143265992 -0.0790832620725363
--0.8193548043760952 0.4791286600785644
--1.272050939831275 0.2416814840895872
+-0.1070913392146362 -0.133818489573786
+-0.3238031557428419 1.287962423435566
+11.31295582996845 -8.341903406741546
+0.1819293433558993 -0.212097135557756
+0.4079441452871376 0.4956876188244267
+0.2350433803187859 0.5501262392487188
+-0.3532073628238944 0.5159478339265959
+-0.7256508946895277 0.1037202403032153
+-0.1339601721612181 -0.08616825417892665
add points to triangulation
added point p8: -1 -0.7369 1.543
9 points, 0 extra points, 9 vertices, and 14 facets in total
added point p9: 0.5112 -0.0827 0.2682
10 points, 0 extra points, 10 vertices, and 16 facets in total
added point p10: 0.06553 -0.5621 0.3202
11 points, 0 extra points, 11 vertices, and 18 facets in total
added point p11: -0.9059 0.3577 0.9486
12 points, 0 extra points, 12 vertices, and 20 facets in total
added point p12: 0.3586 0.8694 0.8844
13 points, 0 extra points, 13 vertices, and 22 facets in total
added point p13: -0.233 0.03883 0.0558
14 points, 0 extra points, 14 vertices, and 24 facets in total
2
-20
--0.5240618706046448 0.8690922898675285
--0.7142921036252496 -0.4804985865634099
--0.3868523717342836 -1.139305762703926
--0.1156818685064501 -0.4320436976219833
-0.1835775895812016 -0.2249639293216311
--0.7258967842870163 0.6025492522388728
--0.7138368277764179 0.3778481824012493
--0.947056678869817 0.1087890172824351
--3.220184924780109 0.005246869469005044
--2.144650850556788 -0.08718357304267166
-0.5665005822680963 2.292036901528415
-0.7037349508716335 0.4364365763155512
--0.4621934658225102 0.1363105721823742
-0.1412729021729308 -0.008672999714931684
--0.5240310768018593 -0.06418916274782284
-0.2007957323480979 0.3558162000371691
--0.5064628004910842 -0.1326436539669383
--0.4489169449937205 -0.1460994267569178
--0.03779347655016083 0.4959031883977701
-0.01966384040606073 0.4848333325721471
+19
+0.4079441452871376 0.4956876188244267
+0.2350433803187859 0.5501262392487188
+-0.3532073628238944 0.5159478339265959
+-0.7256508946895277 0.1037202403032153
+-0.6440941096648549 -0.4633400856225826
+0.1978029374277937 0.01569998052742569
+0.7845449825168889 0.1904844447647789
+0.04950896339507113 -3.798558677118001
+-0.8962486157817683 0.004387728134346125
+-1.089393801767036 -0.1778714260087789
+-0.3389412503887922 0.8905080764495503
+0.2242722217231773 0.5643472284552776
+-0.6044019798647048 1.430953318100048
+-0.3308880091622793 -0.271147084377357
+-0.08301379750248894 -0.2612682965468068
+-0.2978053124441554 0.3637978075255856
+-0.386077459808634 -0.005257450001160686
+0.1313696682445392 -0.069315643871715
+0.1161835094406034 -0.1623083804984112
find Delaunay triangle closest to [0.5, 0.5, ...]
--0.23 0.04
- 0.36 0.87
- 0.51 -0.08
+ 0.41 0.27
+ 0.54 0.68
+ 0.63 0.54
compute halfspace intersection about the origin for a diamond
3
6
0 0 -1
0 -1 0
1 0 0
-1 0 0
0 1 0
0 0 1
add halfspaces for cube to intersection
added offset -1 and normal 1.732 0 0
8 points, 1 extra points, 9 vertices, and 9 facets in total
added offset -1 and normal -1.732 0 0
8 points, 2 extra points, 10 vertices, and 12 facets in total
added offset -1 and normal 0 1.732 0
8 points, 3 extra points, 11 vertices, and 15 facets in total
added offset -1 and normal 0 -1.732 0
8 points, 4 extra points, 12 vertices, and 18 facets in total
added offset -1 and normal 0 0 1.732
8 points, 5 extra points, 13 vertices, and 21 facets in total
added offset -1 and normal 0 0 -1.732
8 points, 6 extra points, 14 vertices, and 24 facets in total
3
24
0.5773502691896257 0 -0.4226497308103742
0.5773502691896257 -0.4226497308103742 0
0.5773502691896257 0.4226497308103742 0
0.5773502691896257 0 0.4226497308103742
-0.5773502691896257 0 -0.4226497308103742
-0.5773502691896257 -0.4226497308103742 0
-0.5773502691896257 0.4226497308103742 0
-0.5773502691896257 0 0.4226497308103742
0 0.5773502691896257 -0.4226497308103742
0.4226497308103742 0.5773502691896257 0
-0.4226497308103742 0.5773502691896257 0
0 0.5773502691896257 0.4226497308103742
0 -0.5773502691896257 -0.4226497308103742
-0.4226497308103742 -0.5773502691896257 0
0.4226497308103742 -0.5773502691896257 0
0 -0.5773502691896257 0.4226497308103742
0 -0.4226497308103742 0.5773502691896257
0.4226497308103742 0 0.5773502691896257
0 0.4226497308103742 0.5773502691896257
-0.4226497308103742 0 0.5773502691896257
-0.4226497308103742 0 -0.5773502691896257
0 -0.4226497308103742 -0.5773502691896257
0.4226497308103742 0 -0.5773502691896257
0 0.4226497308103742 -0.5773502691896257
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96 distance computations.
Convex hull of 14 points in 3-d:
Number of vertices: 14
Number of facets: 24
Statistics for: user_eg cube | qhull s Tcv Q11 QR1 p QR1
Number of points processed: 14
Number of hyperplanes created: 45
Number of distance tests for qhull: 68
Number of distance tests for merging: 370
Number of distance tests for checking: 214
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 192 distance computations.
Voronoi diagram by the convex hull of 8 points in 3-d:
Number of Voronoi regions: 8
Number of Voronoi vertices: 9
Statistics for: user_eg Delaunay | qhull s d Tcv v p
Number of points processed: 8
- Number of hyperplanes created: 21
+ Number of hyperplanes created: 19
Number of facets in hull: 12
- Number of distance tests for qhull: 35
+ Number of distance tests for qhull: 29
CPU seconds to compute hull (after input): 0
-Output completed. Verifying that all points are below 7.5e-015 of
+Output completed. Verifying that all points are below 3.1e-015 of
all facets. Will make 72 distance computations.
Voronoi diagram by the convex hull of 14 points in 3-d:
Number of Voronoi regions: 14
- Number of Voronoi vertices: 20
+ Number of Voronoi vertices: 19
Statistics for: user_eg Delaunay | qhull s d Tcv v p
Number of points processed: 14
- Number of hyperplanes created: 53
+ Number of hyperplanes created: 49
Number of facets in hull: 24
- Number of distance tests for qhull: 81
+ Number of distance tests for qhull: 71
CPU seconds to compute hull (after input): 0
-Output completed. Verifying that all points are below 7.5e-015 of
-all facets. Will make 280 distance computations.
+Output completed. Verifying that all points are below 3.1e-015 of
+all facets. Will make 266 distance computations.
Halfspace intersection by the convex hull of 8 points in 3-d:
Number of halfspaces: 8
Number of non-redundant halfspaces: 8
Number of intersection points: 6
Number of non-simplicial intersection points: 6
Statistics for: user_eg halfspaces | qhull H0 s Tcv Fp
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 142
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
Halfspace intersection by the convex hull of 14 points in 3-d:
Number of halfspaces: 14
Number of non-redundant halfspaces: 14
Number of intersection points: 24
Statistics for: user_eg halfspaces | qhull H0 s Tcv Fp
Number of points processed: 14
Number of hyperplanes created: 35
Number of distance tests for qhull: 59
Number of distance tests for merging: 306
Number of distance tests for checking: 214
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 192 distance computations.
user_eg3 rbox "10 D2" "2 D2" qhull "p"
rbox 10 D2
rbox 2 D2
Results of p
2
5
-0.02222276248244826 -0.4979727817680433
-0.4285431913366012 0.4745826469497594
0.3790312361708201 0.3779794437605696
0.3443122672329771 -0.1437312230875075
-0.3674659290047977 0.0001301793382784133
echo === check front ends ${d:-`date`} ==================
date
-=== check front ends Tue Jan 24 20:16:43 EST 2012 ==================
+=== check front ends Sun Aug 30 22:24:26 EDT 2015 ==================
qconvex -
qconvex- compute the convex hull
- http://www.qhull.org 2012.1 2012/01/22
+ http://www.qhull.org 2015.0.2 2015/08/30
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 - joggled input instead of merged 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)
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
qconvex .
-Qhull 2012.1 2012/01/22.
+Qhull 2015.0.2 2015/08/30.
Except for 'F.' and 'PG', upper-case options take an argument.
incidences mathematica normals OFF_format points
summary facet_dump
Farea FArea_total Fcoplanars FCentrums Fd_cdd_in
FD_cdd_out FFacet_xridge Finner FIDs Fmerges
Fneighbors FNeigh_vertex Fouter FOptions FPoint_near
FQhull Fsummary FSize Fvertices FVertex_ave
Fxtremes FMaple
Gvertices Gpoints Gall_points Gno_planes Ginner
Gcentrums Ghyperplanes Gridges Gouter GDrop_dim
PArea_keep Pdrop d0:0D0 PFacet_area_keep Pgood PGood_neighbors
PMerge_keep Poutput_forced Pprecision_not
QbBound 0:0.5 QbB_scale_box Qcoplanar QGood_point Qinterior
QJoggle Qrandom QRotate Qsearch_1st Qtriangulate
QVertex_good
T4_trace Tcheck_often Tstatistics Tverify Tz_stdout
TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file
TWide_trace TVertex_stop TCone_stop
Angle_max Centrum_size Random_dist Ucoplanar_max Wide_outside
qconvex
-qconvex- compute the convex hull. Qhull 2012.1 2012/01/22
+qconvex- compute the convex hull. Qhull 2015.0.2 2015/08/30
input (stdin): dimension, number of points, point coordinates
comments start with a non-numeric character
options (qconvex.htm):
Qt - triangulated output
QJ - joggled input instead of merged 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 - report total area and volume
FS - 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
rbox c D3 | qconvex s n Qt
4
12
-0 -0 -1 -0.5
-0 -0 -1 -0.5
0 -1 0 -0.5
0 -1 0 -0.5
1 -0 -0 -0.5
1 -0 -0 -0.5
-1 -0 -0 -0.5
-1 -0 -0 -0.5
0 1 -0 -0.5
0 1 -0 -0.5
-0 -0 1 -0.5
-0 -0 1 -0.5
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 12
Number of triangulated facets: 6
Statistics for: rbox c D3 | qconvex s n Qt
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 108
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
rbox c D2 | qconvex s i
4
0 2
1 0
2 3
3 1
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox c D2 | qconvex s i
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 6
CPU seconds to compute hull (after input): 0
rbox c D2 | qconvex o
2
4 4 4
-0.5 -0.5
-0.5 0.5
0.5 -0.5
0.5 0.5
2 0 2
2 1 0
2 2 3
2 3 1
rbox 1000 s | qconvex s Tv FA
Convex hull of 1000 points in 3-d:
Number of vertices: 1000
Number of facets: 1996
Statistics for: rbox 1000 s | qconvex s Tv FA
Number of points processed: 1000
Number of hyperplanes created: 5545
Number of distance tests for qhull: 25488
CPU seconds to compute hull (after input): 0
Total facet area: 3.1201951
Total volume: 0.51650274
qhull output completed. Verifying that 1000 points are
below 2.1e-015 of the nearest facet.
rbox c d D2 | qconvex s Qc Fx
4
0
2
3
1
Convex hull of 8 points in 2-d:
Number of vertices: 4
Number of coplanar points: 4
Number of facets: 4
Statistics for: rbox c d D2 | qconvex s Qc Fx
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 36
CPU seconds to compute hull (after input): 0
rbox y 1000 W0 | qconvex s n
4
4
0.2135848119563837 0.1168704340428167 0.9699086708284445 -0.09806074564261891
0.08553875579270345 -0.8316435307282575 -0.5486822022403077 -0.1234144150397865
-0.749541668500822 -0.02779445272382559 -0.6613733859014792 -0.2159556159595279
0.3120013537900506 0.9498158823230658 -0.02247097950761911 -0.02453689035981485
Convex hull of 1004 points in 3-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox y 1000 W0 | qconvex s n
Number of points processed: 4
Number of hyperplanes created: 5
Number of distance tests for qhull: 11001
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
rbox y 1000 W0 | qconvex s QJ
Convex hull of 1004 points in 3-d:
Number of vertices: 51
Number of facets: 98
Statistics for: rbox y 1000 W0 | qconvex s QJ
Number of points processed: 52
Number of hyperplanes created: 181
Number of distance tests for qhull: 6424
CPU seconds to compute hull (after input): 0
Input joggled by: 2.1e-011
rbox d G1 D12 | qconvex QR0 FA
Convex hull of 24 points in 12-d:
Number of vertices: 24
Number of facets: 4096
-Statistics for: rbox d G1 D12 | qconvex QR0 FA QR1327454203
+Statistics for: rbox d G1 D12 | qconvex QR0 FA QR1440987867
Number of points processed: 24
Number of hyperplanes created: 4108
Number of distance tests for qhull: 4216
Number of distance tests for merging: 121128
Number of distance tests for checking: 196656
Number of merged facets: 2036
- CPU seconds to compute hull (after input): 0.109
+ CPU seconds to compute hull (after input): 0.093
Approximate facet area: 0.00035546337
Approximate volume: 8.5511197e-006
rbox c D6 | qconvex FA TF500
Convex hull of 64 points in 6-d:
Number of vertices: 64
Number of facets: 12
Number of non-simplicial facets: 12
Statistics for: rbox c D6 | qconvex FA TF500
Number of points processed: 64
Number of hyperplanes created: 359
Number of distance tests for qhull: 2510
Number of distance tests for merging: 14115
Number of distance tests for checking: 832
Number of merged facets: 1457
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
Approximate facet area: 12
Approximate volume: 1
-At 20:16:43 & 0 CPU secs, qhull has created 543 facets and merged 289.
+At 22:24:27 & 0 CPU secs, qhull has created 543 facets and merged 289.
The current hull contains 91 facets and 23 vertices. There are 41
outside points. Next is point p27(v24), 0.64 above f107.
-At 20:16:43 & 0 CPU secs, qhull has created 1061 facets and merged 737.
+At 22:24:27 & 0 CPU secs, qhull has created 1061 facets and merged 737.
The current hull contains 69 facets and 33 vertices. There are 31
outside points. Next is point p22(v34), 0.52 above f610.
-At 20:16:43 & 0 CPU secs, qhull has created 1575 facets and merged 1230.
+At 22:24:27 & 0 CPU secs, qhull has created 1575 facets and merged 1230.
The current hull contains 25 facets and 51 vertices. There are 13
outside points. Next is point p45(v52), 0.45 above f1476.
-At 20:16:43 & 0 CPU secs, qhull has created 1815 facets and merged 1457.
+At 22:24:27 & 0.015 CPU secs, qhull has created 1815 facets and merged 1457.
The current hull contains 12 facets and 64 vertices. Last point was p35
Convex hull of 64 points in 6-d:
Number of vertices: 64
Number of facets: 12
Number of non-simplicial facets: 12
Statistics for: rbox c D6 | qconvex FA TF500
Number of points processed: 64
Number of hyperplanes created: 359
Number of distance tests for qhull: 2510
Number of distance tests for merging: 13995
Number of distance tests for checking: 0
Number of merged facets: 1457
First post-merge with 'C3.5e-015' and 'A1.8e+308'
-At 20:16:43 & 0 CPU secs, qhull has created 1815 facets and merged 1457.
+At 22:24:27 & 0.015 CPU secs, qhull has created 1815 facets and merged 1457.
The current hull contains 12 facets and 64 vertices. Last point was p35
Testing all coplanar points.
computing area of each facet and volume of the convex hull
rbox c P0 d D2 | qconvex p Fa Fc FP FI Fn FN FS Fv Fx
2
8
-0.5 -0.5
-0.5 0.5
0.5 -0.5
0.5 0.5
0 -0.5
0 0.5
-0.5 0
0.5 0
4
1
1
1
1
4
1 5
1 7
1 8
1 6
4
3 5 1 0.5
2 7 2 0.5
4 8 4 0.5
4 6 5 0.5
4
1
2
4
5
4
2 1 2
2 0 3
2 0 3
2 1 2
9
0
2 0 1
2 1 3
2 0 2
2 2 3
1 0
1 3
1 1
1 2
0
2 4 1
4
2 3 1
2 2 1
2 4 3
2 4 2
4
1
3
4
2
rbox c d D2 | qconvex s i QV0
2
0 2
1 0
Convex hull of 8 points in 2-d:
Number of vertices: 4
Number of facets: 4
Number of 'good' facets: 2
Statistics for: rbox c d D2 | qconvex s i QV0
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 36
CPU seconds to compute hull (after input): 0
rbox c | qconvex Q0
QH6029 qhull error: option 'Q0' is not used with this program.
It may be used with qhull.
While executing: | qconvex Q0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315181139
+Options selected for Qhull 2015.0.2 2015/08/30:
+ run-id 1509993450
qvoronoi -
qvoronoi- compute the Voronoi diagram
- http://www.qhull.org 2012.1 2012/01/22
+ http://www.qhull.org 2015.0.2 2015/08/30
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:
Qz - add point-at-infinity to Voronoi diagram
Qs - search all points for the initial simplex
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
qvoronoi .
-Qhull 2012.1 2012/01/22.
+Qhull 2015.0.2 2015/08/30.
Except for 'F.' and 'PG', upper-case options take an argument.
OFF_format p_vertices i_delaunay summary facet_dump
Fcoincident Fd_cdd_in FD_cdd_out FF-dump-xridge Fi_bounded
Fxtremes Fmerges Fneighbors FNeigh_region FOptions
Fo_unbounded FPoint_near FQvoronoi Fsummary Fvoronoi
FIDs
Gvertices Gpoints Gall_points Gno_planes Ginner
Gcentrums Ghyperplanes Gridges Gouter GDrop_dim
PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep
PGood_neighbors PMerge_keep Poutput_forced Pprecision_not
QG_vertex_good Qsearch_1st Qupper_voronoi QV_point_good Qzinfinite
T4_trace Tcheck_often Tstatistics Tverify Tz_stdout
TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file
TWide_trace TVertex_stop TCone_stop
Angle_max Centrum_size Random_dist Wide_outside
qvoronoi
-qvoronoi- compute the Voronoi diagram. Qhull 2012.1 2012/01/22
+qvoronoi- compute the Voronoi diagram. Qhull 2015.0.2 2015/08/30
input (stdin): dimension, number of points, point coordinates
comments start with a non-numeric character
options (qvoronoi.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
rbox c P0 D2 | qvoronoi s o
2
5 5 1
-10.101 -10.101
0 -0.5
-0.5 0
0.5 0
0 0.5
4 4 2 1 3
3 2 0 1
3 4 0 2
3 3 0 1
3 4 0 3
Voronoi diagram by the convex hull of 5 points in 3-d:
Number of Voronoi regions: 5
Number of Voronoi vertices: 4
Statistics for: rbox c P0 D2 | qvoronoi s o
Number of points processed: 5
Number of hyperplanes created: 7
Number of facets in hull: 5
Number of distance tests for qhull: 8
Number of distance tests for merging: 29
Number of distance tests for checking: 30
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
rbox c P0 D2 | qvoronoi Fi Tv
4
5 0 3 0.7071067811865475 -0.7071067811865475 -0.3535533905932737
5 0 1 -0.7071067811865475 -0.7071067811865475 -0.3535533905932737
5 0 2 -0.7071067811865475 0.7071067811865475 -0.3535533905932737
5 0 4 0.7071067811865475 0.7071067811865475 -0.3535533905932737
Voronoi ridge statistics
4 bounded ridges
0 max. distance of midpoint to ridge
4 bounded ridges with ok normal
2.2e-016 ave. angle to ridge
2.2e-016 max. angle to ridge
Output completed. Verifying that all points are below outer planes of
all facets. Will make 20 distance computations.
rbox c P0 D2 | qvoronoi Fo
4
5 1 2 -1 0 -0.5
5 1 3 1 -0 -0
5 2 4 1 -0 -0
5 3 4 -1 0 0.5
rbox c P0 D2 | qvoronoi Fv
8
4 0 3 1 3
4 0 1 1 2
4 0 2 2 4
4 0 4 3 4
4 1 2 0 2
4 1 3 0 1
4 2 4 0 4
4 3 4 0 3
rbox c P0 D2 | qvoronoi s Qu Qt Fv
4
4 1 3 0 2
4 1 2 0 1
4 2 4 0 1
4 3 4 0 2
Furthest-site Voronoi vertices by the convex hull of 5 points in 3-d:
Number of Voronoi regions: 5
Number of Voronoi vertices: 2
Number of triangulated facets: 1
Statistics for: rbox c P0 D2 | qvoronoi s Qu Qt Fv
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
rbox c P0 D2 | qvoronoi Qu Fo
4
5 1 2 -0 1 0
5 1 3 1 -0 -0
5 2 4 1 -0 -0
5 3 4 -0 1 -0
rbox c G1 d D2 | qvoronoi s p
2
9
0 -1.75
-1.75 0
-0.5833333333333334 -0.5833333333333333
0 1.75
-0.5833333333333333 0.5833333333333334
1.75 0
0.5833333333333334 -0.5833333333333333
0.5833333333333334 0.5833333333333333
0 0
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 c G1 d D2 | qvoronoi s p
Number of points processed: 8
Number of hyperplanes created: 17
Number of facets in hull: 10
Number of distance tests for qhull: 42
Number of distance tests for merging: 103
Number of distance tests for checking: 80
Number of merged facets: 3
CPU seconds to compute hull (after input): 0
rbox c G1 d D2 | qvoronoi QJ p
2
10
-2.57276422388486e-011 1.749999999802917
-2.05463598231932e-011 -1.750000000331276
0.5833333333083517 -0.5833333333052267
1.862254794815499e-011 -7.815052443180038e-011
1.750000000002628 3.498100747664324e-011
0.5833333333132078 0.5833333333796981
-0.5833333332888888 0.5833333333317835
-7.592293460589872e-011 -7.815050692933324e-011
-1.750000000049026 2.293196879294717e-011
-0.5833333333977308 -0.5833333333229861
rbox c P-0.1 P+0.1 P+0.1 D2 | qvoronoi s Fc FP FQ Fn FN
4
0
1 1
0
0
1
2 1 8 0
rbox c P-0.1 P+0.1 P+0.1 D2 | qvoronoi s Fc FP FQ Fn FN
4
3 -1 2 3
3 -1 2 3
4 -1 0 1 3
4 0 -1 2 1
7
3 3 2 0
1 1
3 3 1 2
3 0 -1 2
3 3 -1 0
3 1 -1 2
3 1 -1 3
Voronoi diagram by the convex hull of 7 points in 3-d:
Number of Voronoi regions: 6
Number of nearly incident points: 1
Number of Voronoi vertices: 4
Number of non-simplicial Voronoi vertices: 2
Statistics for: rbox c P-0.1 P+0.1 P+0.1 D2 | qvoronoi s Fc FP FQ Fn FN
Number of points processed: 6
Number of hyperplanes created: 8
Number of facets in hull: 5
Number of distance tests for qhull: 33
Number of distance tests for merging: 49
Number of distance tests for checking: 43
Number of merged facets: 3
CPU seconds to compute hull (after input): 0
rbox P0 c D2 | qvoronoi s Fv QV0
4
4 0 3 1 3
4 0 1 1 2
4 0 2 2 4
4 0 4 3 4
Voronoi diagram by the convex hull of 5 points in 3-d:
Number of Voronoi regions: 5
Number of 'good' Voronoi vertices: 4
Statistics for: rbox P0 c D2 | qvoronoi s Fv QV0
Number of points processed: 5
Number of hyperplanes created: 7
Number of facets in hull: 5
Number of distance tests for qhull: 8
Number of distance tests for merging: 29
Number of distance tests for checking: 30
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
qdelaunay -
qdelaunay- compute the Delaunay triangulation
- http://www.qhull.org 2012.1 2012/01/22
+ http://www.qhull.org 2015.0.2 2015/08/30
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 Delaunay triangulation
Qt - triangulated output
QJ - joggled input instead of merged facets
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
qdelaunay .
-Qhull 2012.1 2012/01/22.
+Qhull 2015.0.2 2015/08/30.
Except for 'F.' and 'PG', upper-case options take an argument.
incidences mathematica OFF_format points_lifted summary
facet_dump
Farea FArea_total Fcoincident Fd_cdd_in FD_cdd_out
FF_dump_xridge FIDs Fmerges Fneighbors FNeigh_vertex
FOptions FPoint_near FQdelaun Fsummary FSize
Fvertices Fxtremes FMaple
Gvertices Gpoints Gall_points Gno_planes Ginner
Gcentrums Ghyperplanes Gridges Gouter GDrop_dim
Gtransparent
PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep
PGood_neighbors PMerge_keep Poutput_forced Pprecision_not
QGood_point QJoggle Qsearch_1st Qtriangulate QupperDelaunay
QVertex_good Qzinfinite
T4_trace Tcheck_often Tstatistics Tverify Tz_stdout
TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file
TWide_trace TVertex_stop TCone_stop
Angle_max Centrum_size Random_dist Wide_outside
qdelaunay
-qdelaunay- compute the Delaunay triangulation. Qhull 2012.1 2012/01/22
+qdelaunay- compute the Delaunay triangulation. Qhull 2015.0.2 2015/08/30
input (stdin): dimension, number of points, point coordinates
comments start with a non-numeric character
options (qdelaun.htm):
Qu - furthest-site Delaunay triangulation
Qt - triangulated output
QJ - joggled input instead of merged facets
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 D2 | qdelaunay Fv rbox c P0 D2 | qdelaunay s Qu Fv
rbox c G1 d D2 | qdelaunay s i rbox c G1 d D2 | qdelaunay Qt
rbox M3,4 z 100 D2 | qdelaunay s rbox M3,4 z 100 D2 | qdelaunay s Qt
rbox c P0 D2 | qdelaunay s o
3
5 4 6
0 0 0
-0.5 -0.5 1
-0.5 0.5 1
0.5 -0.5 1
0.5 0.5 1
3 3 0 1
3 0 2 1
3 4 0 3
3 0 4 2
Delaunay triangulation by the convex hull of 5 points in 3-d:
Number of input sites: 5
Number of Delaunay regions: 4
Statistics for: rbox c P0 D2 | qdelaunay s o
Number of points processed: 5
Number of hyperplanes created: 7
Number of facets in hull: 5
Number of distance tests for qhull: 8
Number of distance tests for merging: 29
Number of distance tests for checking: 30
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
rbox c P0 D2 | qdelaunay i
4
3 0 1
0 2 1
4 0 3
0 4 2
rbox c P0 D2 | qdelaunay Fv
4
3 0 3 1
3 0 2 1
3 4 0 3
3 4 0 2
rbox c P0 D2 | qdelaunay s Qu Qt Fv
2
3 4 2 1
3 4 3 1
Furthest-site Delaunay triangulation by the convex hull of 5 points in 3-d:
Number of input sites: 5
Number of Delaunay regions: 2
Number of triangulated facets: 1
Statistics for: rbox c P0 D2 | qdelaunay s Qu Qt Fv
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
rbox c G1 d D2 | qdelaunay s i
9
2 4 0
6 1 0
4 6 0
5 3 1
6 5 1
3 7 2
7 4 2
5 7 3
4 7 5 6
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 c G1 d D2 | qdelaunay s i
Number of points processed: 8
Number of hyperplanes created: 17
Number of facets in hull: 10
Number of distance tests for qhull: 42
Number of distance tests for merging: 103
Number of distance tests for checking: 80
Number of merged facets: 3
CPU seconds to compute hull (after input): 0
rbox c G1 d D2 | qhull d Qbb Ft
2
9 12 14
-1 -1
-1 1
1 -1
1 1
0 -0.5
0 0.5
-0.5 0
0.5 0
0 0
3 2 4 0
3 6 1 0
3 4 6 0
3 5 3 1
3 6 5 1
3 3 7 2
3 7 4 2
3 5 7 3
3 8 5 6
3 8 6 4
3 8 4 7
3 8 7 5
rbox c G1 d D2 | qhull d Qbb QJ s Ft
2
8 10 15
-1.000000000061343 -0.999999999957446
-0.9999999999945448 0.9999999999532114
1.000000000029778 -0.9999999999701502
0.9999999999806051 1.000000000003233
-7.748592400792811e-011 -0.5000000000743411
2.849349704487493e-011 0.49999999991804
-0.5000000000721135 -1.37371989142159e-011
0.5000000000148132 7.166044474310069e-011
3 1 5 3
3 2 4 0
3 7 4 2
3 4 7 5
3 3 7 2
3 5 7 3
3 1 6 5
3 6 4 5
3 6 1 0
3 4 6 0
Delaunay triangulation by the convex hull of 8 points in 3-d:
Number of input sites: 8
Number of Delaunay regions: 10
Statistics for: rbox c G1 d D2 | qhull d Qbb QJ s Ft
Number of points processed: 8
Number of hyperplanes created: 20
Number of facets in hull: 12
Number of distance tests for qhull: 32
CPU seconds to compute hull (after input): 0
Input joggled by: 8.3e-011
rbox M3,4 z 100 D2 | qdelaunay s
Delaunay triangulation by the convex hull of 100 points in 3-d:
Number of input sites: 100
Number of Delaunay regions: 81
Number of non-simplicial Delaunay regions: 81
Statistics for: rbox M3,4 z 100 D2 | qdelaunay s
Number of points processed: 100
Number of hyperplanes created: 262
Number of facets in hull: 86
Number of distance tests for qhull: 1652
Number of distance tests for merging: 2778
Number of distance tests for checking: 1348
Number of merged facets: 152
CPU seconds to compute hull (after input): 0
rbox c P-0.1 P+0.1 P+0.1 D2 | qdelaunay s Fx Fa Fc FP FQ Fn FN
4
4
3
6
5
4
0.2
0.2
0.3
0.3
4
0
1 1
0
0
1
2 1 8 0
rbox c P-0.1 P+0.1 P+0.1 D2 | qdelaunay s Fx Fa Fc FP FQ Fn FN
4
3 -1 2 3
3 -1 2 3
4 -1 0 1 3
4 0 -1 2 1
7
3 3 2 0
1 1
3 3 1 2
3 0 -1 2
3 3 -1 0
3 1 -1 2
3 1 -1 3
Delaunay triangulation by the convex hull of 7 points in 3-d:
Number of input sites: 6
Number of nearly incident points: 1
Number of Delaunay regions: 4
Number of non-simplicial Delaunay regions: 2
Statistics for: rbox c P-0.1 P+0.1 P+0.1 D2 | qdelaunay s Fx Fa Fc FP FQ Fn FN
Number of points processed: 6
Number of hyperplanes created: 8
Number of facets in hull: 5
Number of distance tests for qhull: 33
Number of distance tests for merging: 49
Number of distance tests for checking: 42
Number of merged facets: 3
CPU seconds to compute hull (after input): 0
Approximate facet area: 1
rbox P0 P0 c D2 | qdelaunay s FP QV0
1
0 1 2 0
Delaunay triangulation by the convex hull of 6 points in 3-d:
Number of input sites: 5
Number of nearly incident points: 1
Number of 'good' Delaunay regions: 4
Statistics for: rbox P0 P0 c D2 | qdelaunay s FP QV0
Number of points processed: 5
Number of hyperplanes created: 7
Number of facets in hull: 5
Number of distance tests for qhull: 20
Number of distance tests for merging: 29
Number of distance tests for checking: 36
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
qhalf -
qhalf- compute the intersection of halfspaces about a point
- http://www.qhull.org 2012.1 2012/01/22
+ http://www.qhull.org 2015.0.2 2015/08/30
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 output
QJ - joggled input instead of merged 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 visible 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
qhalf .
-Qhull 2012.1 2012/01/22.
+Qhull 2015.0.2 2015/08/30.
Except for 'F.' and 'PG', upper_case options take an argument.
incidences Geomview mathematica OFF_format point_dual
summary facet_dump
Fc_redundant Fd_cdd_in FF_dump_xridge FIDs Fmerges
Fneighbors FN_intersect FOptions Fp_coordinates FP_nearest
FQhalf Fsummary Fv_halfspace FMaple Fx_non_redundant
Gvertices Gpoints Gall_points Gno_planes Ginner
Gcentrums Ghyperplanes Gridges Gouter GDrop_dim
PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep
PGood_neighbors PMerge_keep Poutput_forced Pprecision_not
Qbk:0Bk:0_drop Qcoplanar QG_half_good Qi_redundant QJoggle
Qsearch_1st Qtriangulate QVertex_good
T4_trace Tcheck_often Tstatistics Tverify Tz_stdout
TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file
TWide_trace TVertex_stop TCone_stop
Angle_max Centrum_size Random_dist Ucoplanar_max Wide_outside
qhalf
-qhalf- halfspace intersection about a point. Qhull 2012.1 2012/01/22
+qhalf- halfspace intersection about a point. Qhull 2015.0.2 2015/08/30
input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset
comments start with a non-numeric character
options (qhalf.htm):
Hn,n - specify coordinates of interior point
Qt - triangulated output
QJ - joggled input instead of merged 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 FQ n | qhalf s H0,0,0 Fp
rbox c | qconvex FQ FV n | qhalf s i
rbox c | qconvex FQ FV n | qhalf s o
rbox d | qhull FQ n | qhalf s Qt H0,0,0 Fp
3
12
0 0 0.5
0 0 0.5
0 0.5 0
0 0.5 0
-0.5 0 0
-0.5 0 0
0.5 0 0
0.5 0 0
0 -0.5 0
0 -0.5 0
0 0 -0.5
0 0 -0.5
Halfspace intersection by the convex hull of 8 points in 3-d:
Number of halfspaces: 8
Number of non-redundant halfspaces: 8
Number of intersection points: 12
Number of triangulated facets: 6
Statistics for: rbox d | qhull FQ n | qhalf s Qt H0,0,0 Fp
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 33
Number of distance tests for merging: 119
Number of distance tests for checking: 56
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
rbox c | qhull FQ FV n | qhalf s i
8
4 5 3
5 4 2
0 4 3
4 0 2
1 5 2
5 1 3
1 0 3
0 1 2
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 | qhull FQ FV n | qhalf s i
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 45
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
rbox c | qhull FQ FV n | qhalf o
3
6 8 12
-0 -0 -2
0 -2 0
2 -0 -0
-2 -0 -0
0 2 -0
-0 -0 2
3 4 5 3
3 5 4 2
3 0 4 3
3 4 0 2
3 1 5 2
3 5 1 3
3 1 0 3
3 0 1 2
rbox d D2 | qhull FQ n | qhalf s H0 Fc FP Fn FN FQ Fv Fx
4
0
0
0
0
0
4
2 1 2
2 0 3
2 0 3
2 1 2
4
2 0 1
2 0 2
2 1 3
2 2 3
rbox d D2 | qhull FQ n | qhalf s H0 Fc FP Fn FN FQ Fv Fx
4
2 1 0
2 2 0
2 3 1
2 3 2
4
1
0
2
3
Halfspace intersection by the convex hull of 4 points in 2-d:
Number of halfspaces: 4
Number of non-redundant halfspaces: 4
Number of intersection points: 4
Statistics for: rbox d D2 | qhull FQ n | qhalf s H0 Fc FP Fn FN FQ Fv Fx
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 6
CPU seconds to compute hull (after input): 0
echo === check quality of Qhull for ${d:-`hostname`} ${d:-`date`}
hostname
date
-=== check quality of Qhull for ispy Tue Jan 24 20:16:44 EST 2012
+=== check quality of Qhull for ispy Sun Aug 30 22:24:28 EDT 2015
rbox 1000 W0 | qhull QR2 QJ s Fs Tv
10 3 1000 144 284 144 284 0 0 33 0
2 5.045982607091333e-011 -5.045982607091333e-011
Convex hull of 1000 points in 3-d:
Number of vertices: 144
Number of facets: 284
Statistics for: rbox 1000 W0 | qhull QR2 QJ s Fs Tv QR2
Number of points processed: 171
Number of hyperplanes created: 1233
Number of distance tests for qhull: 33562
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
After 1 retries, input joggled by: 2.9e-011
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 284000 distance computations.
rbox 1000 W0 | qhull QR2 s Fs Tv
10 3 1000 84 98 84 98 0 6 13 0
2 1.942124858599573e-015 -1.241679291552168e-015
Convex hull of 1000 points in 3-d:
Number of vertices: 84
Number of facets: 98
Number of non-simplicial facets: 6
Statistics for: rbox 1000 W0 | qhull QR2 s Fs Tv QR2
Number of points processed: 97
Number of hyperplanes created: 299
Number of distance tests for qhull: 18051
Number of distance tests for merging: 3325
Number of distance tests for checking: 15397
Number of merged facets: 92
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 98000 distance computations.
rbox 1000 s | qhull C0.02 Qc Tv
Convex hull of 1000 points in 3-d:
Number of vertices: 114
Number of coplanar points: 886
Number of facets: 60
Number of non-simplicial facets: 60
Statistics for: rbox 1000 s | qhull C0.02 Qc Tv
Number of points processed: 1000
Number of hyperplanes created: 5545
Number of distance tests for qhull: 83858
Number of distance tests for merging: 82226
Number of distance tests for checking: 7929
Number of merged facets: 1936
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0.016
Maximum distance of vertex below facet: -0.072 (1.2x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 60000 distance computations.
rbox 500 s D4 | qhull C0.01 Qc Tv
Convex hull of 500 points in 4-d:
Number of vertices: 467
Number of coplanar points: 33
Number of facets: 357
Number of non-simplicial facets: 343
Statistics for: rbox 500 s D4 | qhull C0.01 Qc Tv
Number of points processed: 500
Number of hyperplanes created: 11284
Number of distance tests for qhull: 41395
Number of distance tests for merging: 162691
Number of distance tests for checking: 20813
Number of merged facets: 2809
CPU seconds to compute hull (after input): 0.031
Maximum distance of vertex below facet: -0.073 (1.8x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 178500 distance computations.
rbox 1000 s | qhull C-0.02 Qc Tv
Convex hull of 1000 points in 3-d:
Number of vertices: 47
Number of coplanar points: 953
Number of facets: 47
Number of non-simplicial facets: 35
Statistics for: rbox 1000 s | qhull C-0.02 Qc Tv
Number of points processed: 50
Number of hyperplanes created: 199
Number of distance tests for qhull: 52519
Number of distance tests for merging: 2966
Number of distance tests for checking: 24231
Number of merged facets: 98
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.065 (1.1x)
Maximum distance of vertex below facet: -0.062 (1.0x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 47000 distance computations.
rbox 1000 s D4 | qhull C-0.01 Qc Tv
Convex hull of 1000 points in 4-d:
Number of vertices: 117
Number of coplanar points: 883
Number of facets: 232
Number of non-simplicial facets: 149
Statistics for: rbox 1000 s D4 | qhull C-0.01 Qc Tv
Number of points processed: 117
Number of hyperplanes created: 1232
Number of distance tests for qhull: 372627
Number of distance tests for merging: 31334
Number of distance tests for checking: 122166
Number of merged facets: 1167
CPU seconds to compute hull (after input): 0.031
Maximum distance of point above facet: 0.062 (1.5x)
Maximum distance of vertex below facet: -0.064 (1.6x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 232000 distance computations.
rbox 200 s D5 | qhull C-0.01 Qx Qc Tv
Convex hull of 200 points in 5-d:
Number of vertices: 160
Number of coplanar points: 40
Number of facets: 388
Number of non-simplicial facets: 342
Statistics for: rbox 200 s D5 | qhull C-0.01 Qx Qc Tv
Number of points processed: 160
Number of hyperplanes created: 4522
Number of distance tests for qhull: 235312
- Number of distance tests for merging: 143132
+ Number of distance tests for merging: 143140
Number of distance tests for checking: 46266
Number of merged facets: 5940
CPU seconds to compute hull (after input): 0.062
Maximum distance of point above facet: 0.059 (1.2x)
Maximum distance of vertex below facet: -0.11 (2.1x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 77600 distance computations.
rbox 100 s D6 | qhull C-0.001 Qx Qc Tv
Convex hull of 100 points in 6-d:
Number of vertices: 100
Number of facets: 4465
Number of non-simplicial facets: 809
Statistics for: rbox 100 s D6 | qhull C-0.001 Qx Qc Tv
Number of points processed: 100
Number of hyperplanes created: 20175
Number of distance tests for qhull: 33383
Number of distance tests for merging: 299744
Number of distance tests for checking: 66106
Number of merged facets: 3948
- CPU seconds to compute hull (after input): 0.125
+ CPU seconds to compute hull (after input): 0.109
Maximum distance of point above facet: 0.0029 (0.5x)
Maximum distance of vertex below facet: -0.014 (2.4x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 446500 distance computations.
rbox 1000 W1e-4 | qhull C-1e-6 Qc Tv
Convex hull of 1000 points in 3-d:
Number of vertices: 144
Number of coplanar points: 75
Number of facets: 243
Number of non-simplicial facets: 26
Statistics for: rbox 1000 W1e-4 | qhull C-1e-6 Qc Tv
Number of points processed: 185
Number of hyperplanes created: 939
Number of distance tests for qhull: 42000
Number of distance tests for merging: 8652
Number of distance tests for checking: 5684
Number of merged facets: 145
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
Maximum distance of point above facet: 1.3e-006 (0.4x)
Maximum distance of vertex below facet: -3.2e-006 (1.1x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 243000 distance computations.
rbox 1000 W5e-4 D4 | qhull C-1e-5 Qc Tv
Convex hull of 1000 points in 4-d:
Number of vertices: 290
Number of coplanar points: 433
Number of facets: 1296
Number of non-simplicial facets: 154
Statistics for: rbox 1000 W5e-4 D4 | qhull C-1e-5 Qc Tv
Number of points processed: 368
Number of hyperplanes created: 6238
Number of distance tests for qhull: 182095
Number of distance tests for merging: 75580
Number of distance tests for checking: 52937
Number of merged facets: 1353
- CPU seconds to compute hull (after input): 0.031
+ CPU seconds to compute hull (after input): 0.016
Maximum distance of point above facet: 9.1e-005 (2.3x)
Maximum distance of vertex below facet: -0.00012 (2.9x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1296000 distance computations.
rbox 400 W1e-3 D5 | qhull C-1e-5 Qx Qc Tv
Convex hull of 400 points in 5-d:
Number of vertices: 305
Number of coplanar points: 35
Number of facets: 5552
Number of non-simplicial facets: 281
Statistics for: rbox 400 W1e-3 D5 | qhull C-1e-5 Qx Qc Tv
Number of points processed: 336
Number of hyperplanes created: 24527
Number of distance tests for qhull: 251847
Number of distance tests for merging: 277585
Number of distance tests for checking: 61531
Number of merged facets: 1482
CPU seconds to compute hull (after input): 0.093
Maximum distance of point above facet: 5.5e-005 (1.1x)
Maximum distance of vertex below facet: -0.0001 (2.1x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 2220800 distance computations.
echo === check input format etc. ${d:-`date`}
date
-=== check input format etc. Tue Jan 24 20:16:45 EST 2012
+=== check input format etc. Sun Aug 30 22:24:29 EDT 2015
qhull <<EOF
Convex hull of 4 points in 2-d:
Number of vertices: 3
Number of facets: 3
Statistics for: #;laskdjf | qhull
Number of points processed: 3
Number of hyperplanes created: 4
Number of distance tests for qhull: 9
CPU seconds to compute hull (after input): 0
qhull <<EOF
Convex hull of 4 points in 2-d:
Number of vertices: 3
Number of facets: 3
Statistics for: #;laskdjf | qhull
Number of points processed: 3
Number of hyperplanes created: 4
Number of distance tests for qhull: 9
CPU seconds to compute hull (after input): 0
QH7073 qhull warning: instead of 4 2-dimensional points, input contains
4 points and 1 extra coordinates. Line 2 is the first
point, line 1 is the first comment, line 2 is the first long line. Continue with 4 points.
qhull <<EOF
QH7073 qhull warning: instead of 4 2-dimensional points, input contains
3 points and 1 extra coordinates. Line 2 is the first
point, line 1 is the first comment, line 2 is the first long line. Continue with 3 points.
QH6013 qhull input error: input is less than 2-dimensional since it has the same x coordinate
While executing: #;laskdjf | qhull
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315214753 _pre-merge _zero-centrum _max-width 2
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510027064 _pre-merge _zero-centrum _max-width 2
Error-roundoff 1.7e-015 _one-merge 8.6e-015 _near-inside 4.3e-014
Visible-distance 3.4e-015 U-coplanar-distance 3.4e-015
Width-outside 6.9e-015 _wide-facet 2.1e-014
qhull <<EOF
QH7073 qhull warning: instead of 4 2-dimensional points, input contains
3 points and 1 extra coordinates. Line 3 is the first
point, line 2 is the first comment, line 3 is the first short
line, line 4 is the first long line. Continue with 3 points.
QH6013 qhull input error: input is less than 2-dimensional since it has the same x coordinate
While executing: #;laskdjf | qhull
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315214753 _pre-merge _zero-centrum _max-width 2
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510027064 _pre-merge _zero-centrum _max-width 2
Error-roundoff 1.7e-015 _one-merge 8.6e-015 _near-inside 4.3e-014
Visible-distance 3.4e-015 U-coplanar-distance 3.4e-015
Width-outside 6.9e-015 _wide-facet 2.1e-014
qhull <<EOF
Convex hull of 4 points in 2-d:
Number of vertices: 3
Number of facets: 3
Statistics for: | qhull
Number of points processed: 3
Number of hyperplanes created: 4
Number of distance tests for qhull: 9
CPU seconds to compute hull (after input): 0
qhull d Qz <<EOF
Delaunay triangulation by the convex hull of 5 points in 3-d:
Number of input sites and at-infinity: 5
Number of Delaunay regions: 1
Number of non-simplicial Delaunay regions: 1
Statistics for: | qhull d Qz
Number of points processed: 5
Number of hyperplanes created: 7
Number of facets in hull: 5
Number of distance tests for qhull: 6
Number of distance tests for merging: 29
Number of distance tests for checking: 30
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
QH7073 qhull warning: instead of 5 2-dimensional points, input contains
4 points and 1 extra coordinates. Line 1 is the first
point, line 1 is the first long line. Continue with 4 points.
qhull d Q8 Qz <<EOF
Delaunay triangulation by the convex hull of 5 points in 3-d:
Number of input sites and at-infinity: 5
Number of Delaunay regions: 1
Number of non-simplicial Delaunay regions: 1
Statistics for: | qhull d Q8 Qz
Number of points processed: 5
Number of hyperplanes created: 7
Number of facets in hull: 5
Number of distance tests for qhull: 6
Number of distance tests for merging: 29
Number of distance tests for checking: 30
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
QH7073 qhull warning: instead of 5 2-dimensional points, input contains
4 points and 1 extra coordinates. Line 1 is the first
point, line 1 is the first long line. Continue with 4 points.
rbox d h | qhull Fd FV n FD Tcv | qhull Fd H Fp Tcv
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
3
6
0 0 0.5
0 0.5 0
-0.5 0 0
0.5 0 0
0 -0.5 0
0 0 -0.5
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox 10 h | qhull Fd FD p Tcv | qhull Fd d Tcv
Output completed. Verifying that all points are below 1.7e-015 of
all facets. Will make 140 distance computations.
Delaunay triangulation by the convex hull of 9 points in 4-d:
Number of input sites: 9
Number of Delaunay regions: 11
Statistics for: rbox 10 h | qhull Fd FD p Tcv | qhull Fd d Tcv
Number of points processed: 9
Number of hyperplanes created: 34
Number of facets in hull: 22
Number of distance tests for qhull: 46
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.5e-015 of
all facets. Will make 99 distance computations.
echo === check rbox ${d:-`date`}
date
-=== check rbox Tue Jan 24 20:16:46 EST 2012
+=== check rbox Sun Aug 30 22:24:29 EDT 2015
rbox 3 n D2
2
3
0.2234321234034673 0.2236923805658635
-0.4021654933711192 -0.1954478539484068
0.1079163058734651 -0.2506519423338137
rbox 3 D2
2 rbox 3 D2
3
-0.3570490315156514 0.07692619792830779
-0.1013959339832849 -0.1614655765345931
0.2480525339469802 0.01893219260399437
rbox 3 h D2
rbox 3 h D2
begin
3 3 real
1 0.16093073846859 -0.2370837309743126
1 0.3337314574362071 0.02459860548805315
1 0.4287583324394733 0.141286041719174
end
hull
rbox 3 z D2
2 rbox 3 z D2
3
696870 290489
252081 728918
932465 -69056
rbox 3 z h D2
rbox 3 z h D2
begin
3 3 integer
1 -951655 -464136
1 -741320 630989
1 -964370 -171508
end
hull
rbox 3 B10 D2
2 rbox 3 B10 D2
3
6.07777520648928 9.167769643634342
2.704250554278727 -9.661033665445665
7.007182209759188 9.71126632738045
rbox 3 z B10 D2
2 rbox 3 z B10 D2
3
5 2
5 -1
3 9
rbox 4 L2 r D2
2 rbox 4 L2 r D2
6
0.5 0
0.1736481776669304 0.1187823492277694
0.1736481776669304 -0.1187823492277694
-0.1736481776669304 0.1187823492277694
-0.1736481776669304 -0.1187823492277694
-0.5 0
rbox 8 L2 D2
2 rbox 8 L2 D2
8
-9.037112801233254e-006 -0.1339745961747267
-0.4680200990905804 0.01769241704257374
-0.05424246984329754 -0.1325023897522757
0.07519664081423347 -0.1311433207603374
0.1915694083864337 0.1154536646477271
0.4772264523261766 0.01275495170842944
-0.4048291575354194 0.04836693717712182
0.3401207718037282 -0.07435635943071228
rbox 4 L4 r D3
3 rbox 4 L4 r D3
12
0.5 0 0
0.25 0 0.04782181019473453
0.25 0 -0.04782181019473453
3.061616997868383e-017 0.5 0
1.530808498934192e-017 0.25 0.04782181019473453
1.530808498934192e-017 0.25 -0.04782181019473453
-0.5 6.123233995736766e-017 0
-0.25 3.061616997868383e-017 0.04782181019473453
-0.25 3.061616997868383e-017 -0.04782181019473453
-9.184850993605148e-017 -0.5 0
-4.592425496802574e-017 -0.25 0.04782181019473453
-4.592425496802574e-017 -0.25 -0.04782181019473453
rbox 4 L4 s D5 W1e-3
5 rbox 4 L4 s D5 W1e-3
4
-0.1779876601833928 -0.1311655069863711 0.09099061083332423 -0.0147197628642461 0.0491007664448838
0.08530477699633816 0.08551065958609008 0.2073152333839907 -0.05556059038062115 0.04824638578429845
-0.2043906348252541 0.01359444539903207 0.07833891569611255 -0.2253375927975145 0.03863248544102459
0.07678497944972421 0.03657959246981071 0.1769587053753909 0.1423142450665639 -0.04874898497507386
rbox y
3 rbox y
4
-0.3062920647731908 0.1492658412542808 -0.2890111205997049
-0.4099055704752966 -0.2829236833219637 -0.09834729097629646
0.07707741817187275 0.4401626986825491 -0.1855306003107974
-0.2128018845923262 0.4387234094913336 -0.3756640258949846
rbox 10 M3,4
3 rbox 10 M3,4
10
0 0 0
3 4 0
6 8 0
-4 3 0
-1 7 0
2 11 0
-8 6 0
-5 10 0
-2 14 0
0 0 5
rbox 10 L2 s D3 | qhull Tcv
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 L2 s D3 | qhull Tcv
Number of points processed: 10
Number of hyperplanes created: 29
Number of distance tests for qhull: 50
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.5e-015 of
all facets. Will make 160 distance computations.
rbox 10 L4 s W1e-3 D3 | qhull Tcv
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 L4 s W1e-3 D3 | qhull Tcv
Number of points processed: 10
Number of hyperplanes created: 27
Number of distance tests for qhull: 43
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.9e-015 of
all facets. Will make 160 distance computations.
rbox 10 L6 D3 | qhull Tcv
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 L6 D3 | qhull Tcv
Number of points processed: 10
Number of hyperplanes created: 29
Number of distance tests for qhull: 48
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.7e-015 of
all facets. Will make 160 distance computations.
rbox 10 L1.1 s D4 | qhull Tcv
Convex hull of 10 points in 4-d:
Number of vertices: 10
Number of facets: 26
Statistics for: rbox 10 L1.1 s D4 | qhull Tcv
Number of points processed: 10
Number of hyperplanes created: 44
Number of distance tests for qhull: 53
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.4e-015 of
all facets. Will make 260 distance computations.
rbox y r 100 W0 O0.5 | qhull s p Tcv
3
4
1 0.5 0.5
0.5 1 0.5
0.5 0.5 1
0 0 0
Convex hull of 104 points in 3-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox y r 100 W0 O0.5 | qhull s p Tcv
Number of points processed: 4
Number of hyperplanes created: 5
Number of distance tests for qhull: 1101
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 416 distance computations.
rbox x r 100 W0 O0.5 | qhull s Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 27
Number of facets: 35
Number of non-simplicial facets: 4
Statistics for: rbox x r 100 W0 O0.5 | qhull s Tcv
Number of points processed: 27
Number of hyperplanes created: 76
Number of distance tests for qhull: 1285
Number of distance tests for merging: 774
Number of distance tests for checking: 905
Number of merged facets: 15
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 3500 distance computations.
rbox 12 D8 | qhull Tcv
Convex hull of 12 points in 8-d:
Number of vertices: 12
Number of facets: 92
Statistics for: rbox 12 D8 | qhull Tcv
Number of points processed: 12
Number of hyperplanes created: 132
Number of distance tests for qhull: 91
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below 7.9e-015 of
all facets. Will make 1104 distance computations.
rbox 12 D9 | qhull Tcv
Convex hull of 12 points in 9-d:
Number of vertices: 12
Number of facets: 70
Statistics for: rbox 12 D9 | qhull Tcv
Number of points processed: 12
Number of hyperplanes created: 89
Number of distance tests for qhull: 47
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below 9e-015 of
all facets. Will make 840 distance computations.
rbox 1000 D4 | qhull s i A-0.97 C0.2 A0.7 Tcv
48
117 111 263 638
117 263 111 146
117 263 146 638
117 146 111 638
118 111 771 456
118 111 146 638
118 146 111 456
118 771 146 456
118 771 430 465
118 771 465 638
118 771 111 638
118 146 771 638
118 465 430 638
118 430 771 638
119 771 263 299
119 430 465 638
119 111 263 771
119 771 430 638
119 465 299 638
119 263 111 638
119 430 771 299
119 111 771 638
119 299 263 638
119 430 299 465
120 430 771 465
120 299 465 638
120 263 771 299
120 146 263 638
120 299 430 465
120 465 771 638
120 263 146 299
120 771 263 456
120 299 771 456
120 771 430 299
120 771 146 638
120 146 771 299
120 263 299 456
120 263 299 638
121 111 146 456
121 146 263 299
121 771 299 456
121 771 146 299
121 263 111 771
121 146 771 456
121 299 263 456
121 111 263 146
121 771 111 456
121 263 771 456
Convex hull of 1000 points in 4-d:
Number of vertices: 9
Number of facets: 5
Number of non-simplicial facets: 4
Statistics for: rbox 1000 D4 | qhull s i A-0.97 C0.2 A0.7 Tcv
Number of points processed: 116
Number of hyperplanes created: 2284
Number of distance tests for qhull: 518926
Number of distance tests for merging: 76090
Number of distance tests for checking: 5989
Number of merged facets: 1889
- CPU seconds to compute hull (after input): 0.047
+ CPU seconds to compute hull (after input): 0.062
Maximum distance of point above facet: 0.07
Maximum distance of vertex below facet: -0.92 (0.6x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 5000 distance computations.
rbox 3 D2 | qhull Qb0B1:-2 p
2
3
-0.5 -2
-0.1839506649197531 -0.1614655765345934
0.2480525339469802 -1.552736350137872
rbox 100 r D2 | qhull Pd0:0.7 PD0:0.8 n Tcv
3
6
0.7501110696304588 0.6613118653236527 -0.4997532801828658
0.7071067811865485 0.7071067811865467 -0.4997532801828658
0.7501110696304543 -0.6613118653236579 -0.4997532801828658
0.7901550123756914 0.6129070536529753 -0.4997532801828658
0.7901550123756885 -0.6129070536529789 -0.4997532801828659
0.707106781186544 -0.7071067811865511 -0.4997532801828658
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 600 distance computations.
rbox 1000 s | qhull C0.05 Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 48
Number of facets: 26
Number of non-simplicial facets: 26
Statistics for: rbox 1000 s | qhull C0.05 Tcv
Number of points processed: 1000
Number of hyperplanes created: 5545
Number of distance tests for qhull: 55658
Number of distance tests for merging: 100391
Number of distance tests for checking: 6790
Number of merged facets: 1970
CPU seconds to compute hull (after input): 0.031
Maximum distance of vertex below facet: -0.21 (1.4x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 26000 distance computations.
rbox 1000 s t | qhull Qm C0.05 Tcv
Convex hull of 1000 points in 3-d:
- Number of vertices: 42
- Number of facets: 23
- Number of non-simplicial facets: 23
+ Number of vertices: 43
+ Number of facets: 24
+ Number of non-simplicial facets: 24
-Statistics for: rbox 1000 s t1327454206 | qhull Qm C0.05 Tcv
+Statistics for: rbox 1000 s t1440987870 | qhull Qm C0.05 Tcv
Number of points processed: 1000
- Number of hyperplanes created: 5585
- Number of distance tests for qhull: 54997
- Number of distance tests for merging: 100488
- Number of distance tests for checking: 6510
- Number of merged facets: 1973
- CPU seconds to compute hull (after input): 0.031
- Maximum distance of vertex below facet: -0.19 (1.3x)
+ Number of hyperplanes created: 5482
+ Number of distance tests for qhull: 54416
+ Number of distance tests for merging: 99556
+ Number of distance tests for checking: 6486
+ Number of merged facets: 1972
+ CPU seconds to compute hull (after input): 0.016
+ Maximum distance of vertex below facet: -0.17 (1.1x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 23000 distance computations.
+all facets. Will make 24000 distance computations.
rbox 500 D2 | qhull n A-0.95 C0.1 Tcv
3
4
0.004814116480453948 0.9999884120741163 -0.4852084337990873
-0.9999815737204624 -0.006070602898184517 -0.4913197370926178
-0.006423098021811921 -0.9999793716931376 -0.4958250456626817
0.9999972817907392 0.002331611273993484 -0.4974344499395051
Output completed. Verifying that all points are below outer planes of
all facets. Will make 2000 distance computations.
rbox 500 s P1,1,1 | qhull QgG0 Pp Tcv
Convex hull of 500 points in 3-d:
Number of vertices: 226
Number of facets: 448
Number of 'good' facets: 340
Statistics for: rbox 500 s P1,1,1 | qhull QgG0 Pp Tcv
Number of points processed: 294
Number of hyperplanes created: 1612
Number of distance tests for qhull: 9968
CPU seconds to compute hull (after input): 0
rbox d | qhull m
{
Polygon[{{ 0.00000000, 0.50000000, 0.00000000},
{ 0.00000000, 0.00000000, 0.50000000},
{ -0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, 0.00000000, 0.50000000},
{ 0.00000000, 0.50000000, 0.00000000},
{ 0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, 0.00000000, -0.50000000},
{ 0.00000000, 0.50000000, 0.00000000},
{ -0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, 0.50000000, 0.00000000},
{ 0.00000000, 0.00000000, -0.50000000},
{ 0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, -0.50000000, 0.00000000},
{ 0.00000000, 0.00000000, 0.50000000},
{ 0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, 0.00000000, 0.50000000},
{ 0.00000000, -0.50000000, 0.00000000},
{ -0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, -0.50000000, 0.00000000},
{ 0.00000000, 0.00000000, -0.50000000},
{ -0.50000000, 0.00000000, 0.00000000}}],
Polygon[{{ 0.00000000, 0.00000000, -0.50000000},
{ 0.00000000, -0.50000000, 0.00000000},
{ 0.50000000, 0.00000000, 0.00000000}}]}
rbox d | qhull FM
PLOT3D(POLYGONS(
[[ 0.00000000, 0.50000000, 0.00000000],
[ 0.00000000, 0.00000000, 0.50000000],
[ -0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, 0.00000000, 0.50000000],
[ 0.00000000, 0.50000000, 0.00000000],
[ 0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, 0.00000000, -0.50000000],
[ 0.00000000, 0.50000000, 0.00000000],
[ -0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, 0.50000000, 0.00000000],
[ 0.00000000, 0.00000000, -0.50000000],
[ 0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, -0.50000000, 0.00000000],
[ 0.00000000, 0.00000000, 0.50000000],
[ 0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, 0.00000000, 0.50000000],
[ 0.00000000, -0.50000000, 0.00000000],
[ -0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, -0.50000000, 0.00000000],
[ 0.00000000, 0.00000000, -0.50000000],
[ -0.50000000, 0.00000000, 0.00000000]],
[[ 0.00000000, 0.00000000, -0.50000000],
[ 0.00000000, -0.50000000, 0.00000000],
[ 0.50000000, 0.00000000, 0.00000000]]));
rbox c D2 | qhull Tcv Q0
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox c D2 | qhull Tcv Q0
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 16 distance computations.
rbox d D2 | qhull Tcv
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox d D2 | qhull Tcv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 4
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 16 distance computations.
rbox c D3 | qhull Tcv Q0
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 12
Statistics for: rbox c D3 | qhull Tcv Q0
Number of points processed: 8
Number of hyperplanes created: 17
Number of distance tests for qhull: 35
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
12 coplanar half ridges in output
6 coplanar horizon facets for new vertices
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 96 distance computations.
rbox d D3 | qhull Tcv
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qhull Tcv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox c D4 | qhull Tcv Q0
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 44
Statistics for: rbox c D4 | qhull Tcv Q0
Number of points processed: 16
Number of hyperplanes created: 62
Number of distance tests for qhull: 163
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
80 coplanar half ridges in output
32 coplanar horizon facets for new vertices
Output completed. Verifying that all points are below 3e-015 of
all facets. Will make 704 distance computations.
rbox d D4 | qhull Tcv
Convex hull of 8 points in 4-d:
Number of vertices: 8
Number of facets: 16
Statistics for: rbox d D4 | qhull Tcv
Number of points processed: 8
Number of hyperplanes created: 20
Number of distance tests for qhull: 24
Number of distance tests for merging: 165
Number of distance tests for checking: 136
Number of merged facets: 4
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 128 distance computations.
rbox c D5 | qhull Tcv Q0
Convex hull of 32 points in 5-d:
Number of vertices: 32
Number of facets: 210
Statistics for: rbox c D5 | qhull Tcv Q0
Number of points processed: 32
Number of hyperplanes created: 297
Number of distance tests for qhull: 856
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
590 coplanar half ridges in output
200 coplanar horizon facets for new vertices
190 nearly singular or axis-parallel hyperplanes
190 zero divisors during back substitute
246 zero divisors during gaussian elimination
Output completed. Verifying that all points are below 4.1e-015 of
all facets. Will make 6720 distance computations.
rbox d D5 | qhull Tcv
Convex hull of 10 points in 5-d:
Number of vertices: 10
Number of facets: 32
Statistics for: rbox d D5 | qhull Tcv
Number of points processed: 10
Number of hyperplanes created: 37
Number of distance tests for qhull: 47
Number of distance tests for merging: 510
Number of distance tests for checking: 330
Number of merged facets: 11
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 320 distance computations.
rbox c D6 | qhull Tcv Q0
Convex hull of 64 points in 6-d:
Number of vertices: 64
Number of facets: 1242
Statistics for: rbox c D6 | qhull Tcv Q0
Number of points processed: 64
Number of hyperplanes created: 1760
Number of distance tests for qhull: 5986
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
4752 coplanar half ridges in output
1382 coplanar horizon facets for new vertices
1180 nearly singular or axis-parallel hyperplanes
1180 zero divisors during back substitute
1593 zero divisors during gaussian elimination
Output completed. Verifying that all points are below 5.3e-015 of
all facets. Will make 79488 distance computations.
rbox d D6 | qhull Tcv
Convex hull of 12 points in 6-d:
Number of vertices: 12
Number of facets: 64
Statistics for: rbox d D6 | qhull Tcv
Number of points processed: 12
Number of hyperplanes created: 70
Number of distance tests for qhull: 88
Number of distance tests for merging: 1176
Number of distance tests for checking: 780
Number of merged facets: 26
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 768 distance computations.
rbox d D7 | qhull Tcv
Convex hull of 14 points in 7-d:
Number of vertices: 14
Number of facets: 128
Statistics for: rbox d D7 | qhull Tcv
Number of points processed: 14
Number of hyperplanes created: 135
Number of distance tests for qhull: 163
Number of distance tests for merging: 2635
Number of distance tests for checking: 1806
Number of merged facets: 57
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1792 distance computations.
rbox c D2 | qhull Tcv C-0
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox c D2 | qhull Tcv C-0
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 16 distance computations.
rbox c D3 | qhull Tcv C-0
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 D3 | qhull Tcv C-0
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 142
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox c D4 | qhull Tcv C-0
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of non-simplicial facets: 8
Statistics for: rbox c D4 | qhull Tcv C-0
Number of points processed: 16
Number of hyperplanes created: 26
Number of distance tests for qhull: 168
Number of distance tests for merging: 788
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 128 distance computations.
rbox c D5 | qhull Tcv C-0
Convex hull of 32 points in 5-d:
Number of vertices: 32
Number of facets: 10
Number of non-simplicial facets: 10
Statistics for: rbox c D5 | qhull Tcv C-0
Number of points processed: 32
Number of hyperplanes created: 87
Number of distance tests for qhull: 722
Number of distance tests for merging: 4130
Number of distance tests for checking: 352
Number of merged facets: 210
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 320 distance computations.
rbox c D6 | qhull Tcv C-0
Convex hull of 64 points in 6-d:
Number of vertices: 64
Number of facets: 12
Number of non-simplicial facets: 12
Statistics for: rbox c D6 | qhull Tcv C-0
Number of points processed: 64
Number of hyperplanes created: 354
Number of distance tests for qhull: 2474
Number of distance tests for merging: 22065
Number of distance tests for checking: 832
Number of merged facets: 1488
CPU seconds to compute hull (after input): 0.046
Output completed. Verifying that all points are below outer planes of
all facets. Will make 768 distance computations.
rbox c D7 | qhull Tv C-0
Convex hull of 128 points in 7-d:
Number of vertices: 128
Number of facets: 14
Number of non-simplicial facets: 14
Statistics for: rbox c D7 | qhull Tv C-0
Number of points processed: 128
Number of hyperplanes created: 1786
Number of distance tests for qhull: 9309
Number of distance tests for merging: 88772
Number of distance tests for checking: 1920
Number of merged facets: 11556
CPU seconds to compute hull (after input): 0.078
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1792 distance computations.
rbox 20 l D3 | qhull Tcv
Convex hull of 20 points in 3-d:
Number of vertices: 20
Number of facets: 36
Statistics for: rbox 20 l D3 | qhull Tcv
Number of points processed: 20
Number of hyperplanes created: 63
Number of distance tests for qhull: 139
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 720 distance computations.
rbox 100 s D2 | qhull Tcv
Convex hull of 100 points in 2-d:
Number of vertices: 100
Number of facets: 100
Statistics for: rbox 100 s D2 | qhull Tcv
Number of points processed: 100
Number of hyperplanes created: 198
Number of distance tests for qhull: 898
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 10000 distance computations.
rbox 100 s D3 | qhull Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 s D3 | qhull Tcv
Number of points processed: 100
Number of hyperplanes created: 514
Number of distance tests for qhull: 1691
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 19600 distance computations.
rbox 100 s D4 | qhull Tcv
Convex hull of 100 points in 4-d:
Number of vertices: 100
Number of facets: 584
Statistics for: rbox 100 s D4 | qhull Tcv
Number of points processed: 100
Number of hyperplanes created: 1718
Number of distance tests for qhull: 4091
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
Output completed. Verifying that all points are below 2.8e-015 of
all facets. Will make 58400 distance computations.
rbox 100 s c D4 | qhull Tcv
Convex hull of 116 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of non-simplicial facets: 8
Statistics for: rbox 100 s c D4 | qhull Tcv
Number of points processed: 16
Number of hyperplanes created: 26
Number of distance tests for qhull: 2028
Number of distance tests for merging: 788
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 928 distance computations.
rbox 100 s d G1.5 D4 | qhull Tcv
Convex hull of 108 points in 4-d:
Number of vertices: 8
Number of facets: 16
Statistics for: rbox 100 s d G1.5 D4 | qhull Tcv
Number of points processed: 8
Number of hyperplanes created: 20
Number of distance tests for qhull: 1457
Number of distance tests for merging: 165
Number of distance tests for checking: 136
Number of merged facets: 4
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1728 distance computations.
rbox 100 s W1e-2 | qhull Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 s W1e-2 | qhull Tcv
Number of points processed: 100
Number of hyperplanes created: 493
Number of distance tests for qhull: 1582
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 19600 distance computations.
rbox 100 | qhull Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 30
Number of facets: 56
Statistics for: rbox 100 | qhull Tcv
Number of points processed: 31
Number of hyperplanes created: 117
Number of distance tests for qhull: 1211
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 5600 distance computations.
rbox 100 W1e-3 | qhull Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 60
Number of facets: 116
Statistics for: rbox 100 W1e-3 | qhull Tcv
Number of points processed: 65
Number of hyperplanes created: 298
Number of distance tests for qhull: 1753
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 11600 distance computations.
rbox 100 r D2 | qhull Tcv
Convex hull of 100 points in 2-d:
Number of vertices: 100
Number of facets: 100
Statistics for: rbox 100 r D2 | qhull Tcv
Number of points processed: 100
Number of hyperplanes created: 198
Number of distance tests for qhull: 853
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 10000 distance computations.
rbox 100 r s Z1 | qhull Tcv
Convex hull of 102 points in 3-d:
Number of vertices: 102
Number of facets: 200
Statistics for: rbox 100 r s Z1 | qhull Tcv
Number of points processed: 102
Number of hyperplanes created: 299
Number of distance tests for qhull: 1457
Number of distance tests for merging: 16912
Number of distance tests for checking: 2604
Number of merged facets: 97
CPU seconds to compute hull (after input): 0.015
Output completed. Verifying that all points are below outer planes of
all facets. Will make 20400 distance computations.
rbox 100 r s Z1 G0.1 | qhull Tcv C-0
Convex hull of 201 points in 3-d:
Number of vertices: 201
Number of facets: 201
Number of non-simplicial facets: 101
Statistics for: rbox 100 r s Z1 G0.1 | qhull Tcv C-0
Number of points processed: 201
Number of hyperplanes created: 994
Number of distance tests for qhull: 6676
Number of distance tests for merging: 38219
Number of distance tests for checking: 11601
Number of merged facets: 323
- CPU seconds to compute hull (after input): 0.046
+ CPU seconds to compute hull (after input): 0.031
Output completed. Verifying that all points are below outer planes of
all facets. Will make 40401 distance computations.
rbox 100 s Z1 G0.1 | qhull Tcv
Convex hull of 101 points in 3-d:
Number of vertices: 101
Number of facets: 198
Statistics for: rbox 100 s Z1 G0.1 | qhull Tcv
Number of points processed: 101
Number of hyperplanes created: 460
Number of distance tests for qhull: 1622
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 19998 distance computations.
rbox 100 s Z1e-5 G0.1 | qhull Tc Pp
Convex hull of 101 points in 3-d:
Number of vertices: 101
Number of facets: 196
Number of non-simplicial facets: 2
Statistics for: rbox 100 s Z1e-5 G0.1 | qhull Tc Pp
Number of points processed: 101
Number of hyperplanes created: 453
Number of distance tests for qhull: 1848
Number of distance tests for merging: 2108
Number of distance tests for checking: 1274
Number of merged facets: 3
CPU seconds to compute hull (after input): 0
Maximum distance of vertex below facet: -1.1e-015 (0.3x)
echo === check qhull output formats ${d:-`date`}
date
-=== check qhull output formats Tue Jan 24 20:16:48 EST 2012
+=== check qhull output formats Sun Aug 30 22:24:32 EDT 2015
rbox 5 r s D2 | qhull Tcv
Convex hull of 5 points in 2-d:
Number of vertices: 5
Number of facets: 5
Statistics for: rbox 5 r s D2 | qhull Tcv
Number of points processed: 5
Number of hyperplanes created: 8
Number of distance tests for qhull: 8
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 25 distance computations.
rbox 5 r s D2 | qhull s
Convex hull of 5 points in 2-d:
Number of vertices: 5
Number of facets: 5
Statistics for: rbox 5 r s D2 | qhull s
Number of points processed: 5
Number of hyperplanes created: 8
Number of distance tests for qhull: 8
CPU seconds to compute hull (after input): 0
rbox 5 r s D2 | qhull s o
2
5 5 5
0.1545084971874737 0.4755282581475768
-0.4045084971874737 0.2938926261462366
-0.4045084971874738 -0.2938926261462365
0.1545084971874736 -0.4755282581475768
0.5 -1.224646799147353e-016
2 4 0
2 2 3
2 3 4
2 1 2
2 0 1
Convex hull of 5 points in 2-d:
Number of vertices: 5
Number of facets: 5
Statistics for: rbox 5 r s D2 | qhull s o
Number of points processed: 5
Number of hyperplanes created: 8
Number of distance tests for qhull: 8
CPU seconds to compute hull (after input): 0
rbox 5 r s D2 | qhull f
Vertices and facets:
- p0(v2): 0.15 0.48
- p4(v1): 0.5 -1.2e-016
- p3(v4): 0.15 -0.48
- p2(v0): -0.4 -0.29
- p1(v5): -0.4 0.29
- f3
- flags: bottom simplicial
- normal: 0.809 0.5878
- offset: -0.4045085
- vertices: p0(v2) p4(v1)
- neighboring facets: f5 f7
- f4
- flags: bottom simplicial
- normal: -0.309 -0.9511
- offset: -0.4045085
- vertices: p3(v4) p2(v0)
- neighboring facets: f6 f5
- f5
- flags: top simplicial
- normal: 0.809 -0.5878
- offset: -0.4045085
- vertices: p3(v4) p4(v1)
- neighboring facets: f3 f4
- f6
- flags: top simplicial
- normal: -1 9.444e-017
- offset: -0.4045085
- vertices: p1(v5) p2(v0)
- neighboring facets: f4 f7
- f7
- flags: bottom simplicial
- normal: -0.309 0.9511
- offset: -0.4045085
- vertices: p1(v5) p0(v2)
- neighboring facets: f3 f6
rbox 5 r s D2 | qhull i
5
4 0
2 3
3 4
1 2
0 1
rbox 5 r s D2 | qhull m
{
Line[{{ 0.50000000, -0.00000000}, { 0.15450850, 0.47552826}}]
,Line[{{ -0.40450850, -0.29389263}, { 0.15450850, -0.47552826}}]
,Line[{{ 0.15450850, -0.47552826}, { 0.50000000, -0.00000000}}]
,Line[{{ -0.40450850, 0.29389263}, { -0.40450850, -0.29389263}}]
,Line[{{ 0.15450850, 0.47552826}, { -0.40450850, 0.29389263}}]
}
rbox 5 r s D2 | qhull FM
PLOT(CURVES(
[[ 0.50000000, -0.00000000], [ 0.15450850, 0.47552826]]
,[[ -0.40450850, -0.29389263], [ 0.15450850, -0.47552826]]
,[[ 0.15450850, -0.47552826], [ 0.50000000, -0.00000000]]
,[[ -0.40450850, 0.29389263], [ -0.40450850, -0.29389263]]
,[[ 0.15450850, 0.47552826], [ -0.40450850, 0.29389263]]
));
rbox 5 r s D2 | qhull n
3
5
0.8090169943749476 0.587785252292473 -0.4045084971874737
-0.3090169943749476 -0.9510565162951536 -0.4045084971874738
0.8090169943749472 -0.5877852522924733 -0.4045084971874737
-1 9.444121133484361e-017 -0.4045084971874738
-0.3090169943749474 0.9510565162951536 -0.4045084971874738
rbox 5 r s D2 | qhull p
2
5
0.1545084971874737 0.4755282581475768
-0.4045084971874737 0.2938926261462366
-0.4045084971874738 -0.2938926261462365
0.1545084971874736 -0.4755282581475768
0.5 -1.224646799147353e-016
rbox 5 r s D2 | qhull o
2
5 5 5
0.1545084971874737 0.4755282581475768
-0.4045084971874737 0.2938926261462366
-0.4045084971874738 -0.2938926261462365
0.1545084971874736 -0.4755282581475768
0.5 -1.224646799147353e-016
2 4 0
2 2 3
2 3 4
2 1 2
2 0 1
rbox 5 r s D2 | qhull Ft
2
5 5 5
0.1545084971874737 0.4755282581475768
-0.4045084971874737 0.2938926261462366
-0.4045084971874738 -0.2938926261462365
0.1545084971874736 -0.4755282581475768
0.5 -1.224646799147353e-016
2 4 0
2 2 3
2 3 4
2 1 2
2 0 1
rbox 5 r s D2 | qhull Fx
5
4
0
1
2
3
rbox 5 r s D2 | qhull p n i p p
2
5
0.1545084971874737 0.4755282581475768
-0.4045084971874737 0.2938926261462366
-0.4045084971874738 -0.2938926261462365
0.1545084971874736 -0.4755282581475768
0.5 -1.224646799147353e-016
3
5
0.8090169943749476 0.587785252292473 -0.4045084971874737
-0.3090169943749476 -0.9510565162951536 -0.4045084971874738
0.8090169943749472 -0.5877852522924733 -0.4045084971874737
-1 9.444121133484361e-017 -0.4045084971874738
-0.3090169943749474 0.9510565162951536 -0.4045084971874738
5
4 0
2 3
3 4
1 2
0 1
rbox 10 D3 | qhull f Tcv
Vertices and facets:
- p0(v5): -0.022 -0.37 0.33
- p9(v2): 0.38 -0.47 -0.22
- p6(v0): -0.31 -0.011 -0.49
- p1(v3): -0.067 -0.16 0.46
- p7(v1): 0.39 0.045 0.12
- p3(v6): 0.31 0.084 -0.1
- p4(v7): 0.18 0.12 0.049
- p5(v8): -0.12 0.015 -0.14
- p2(v9): 0.028 0.042 0.058
- f5
- flags: top simplicial
- normal: -0.4934 -0.8471 -0.1973
- offset: -0.2568231
- vertices: p0(v5) p9(v2) p6(v0)
- neighboring facets: f9 f6 f7
- f6
- flags: bottom simplicial
- normal: -0.9301 -0.3157 0.1877
- offset: -0.1977325
- vertices: p0(v5) p1(v3) p6(v0)
- neighboring facets: f17 f5 f8
- f7
- flags: bottom simplicial
- normal: 0.7008 -0.3956 0.5936
- offset: -0.323519
- vertices: p0(v5) p9(v2) p7(v1)
- neighboring facets: f10 f8 f5
- f8
- flags: top simplicial
- normal: 0.6544 -0.298 0.6949
- offset: -0.3219447
- vertices: p0(v5) p1(v3) p7(v1)
- neighboring facets: f13 f7 f6
- f9
- flags: bottom simplicial
- normal: 0.4866 0.2316 -0.8424
- offset: -0.2582907
- vertices: p3(v6) p9(v2) p6(v0)
- neighboring facets: f5 f16 f10
- f10
- flags: top simplicial
- normal: 0.943 0.1711 -0.2855
- offset: -0.3386013
- vertices: p3(v6) p9(v2) p7(v1)
- neighboring facets: f7 f14 f9
- f13
- flags: bottom simplicial
- normal: 0.08536 0.8035 0.5892
- offset: -0.1388354
- vertices: p4(v7) p1(v3) p7(v1)
- neighboring facets: f8 f14 f20
- f14
- flags: top simplicial
- normal: 0.3121 0.948 0.06295
- offset: -0.1707289
- vertices: p4(v7) p3(v6) p7(v1)
- neighboring facets: f10 f13 f16
- f16
- flags: bottom simplicial
- normal: -0.008104 0.9738 -0.2271
- offset: -0.1026508
- vertices: p4(v7) p3(v6) p6(v0)
- neighboring facets: f9 f18 f14
- f17
- flags: top simplicial
- normal: -0.6179 0.7381 0.2709
- offset: -0.04995414
- vertices: p5(v8) p1(v3) p6(v0)
- neighboring facets: f6 f18 f21
- f18
- flags: bottom simplicial
- normal: -0.3978 0.9064 0.1423
- offset: -0.04320607
- vertices: p5(v8) p4(v7) p6(v0)
- neighboring facets: f16 f17 f22
- f20
- flags: top simplicial
- normal: -0.4124 0.8514 0.3242
- offset: -0.04294297
- vertices: p2(v9) p4(v7) p1(v3)
- neighboring facets: f13 f21 f22
- f21
- flags: bottom simplicial
- normal: -0.5086 0.8133 0.2826
- offset: -0.03620543
- vertices: p2(v9) p5(v8) p1(v3)
- neighboring facets: f17 f20 f22
- f22
- flags: top simplicial
- normal: -0.432 0.8759 0.2148
- offset: -0.03703814
- vertices: p2(v9) p5(v8) p4(v7)
- neighboring facets: f18 f20 f21
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 140 distance computations.
rbox 10 D3 | qhull i
14
0 9 6
1 0 6
9 0 7
0 1 7
9 3 6
3 9 7
1 4 7
4 3 7
3 4 6
5 1 6
4 5 6
2 4 1
5 2 1
2 5 4
rbox 10 D3 | qhull p
3
9
-0.0222149361131852 -0.366434993563625 0.3270621312102882
-0.06676722137887703 -0.1566931052661437 0.4589771055234383
0.02820502736438535 0.04189077954915421 0.05832764185809314
0.3126723396709863 0.08400649026409401 -0.1029227018383543
0.1781470954214661 0.1182274414396169 0.04860343742054274
-0.1220315663349177 0.01546165115708642 -0.1360330368727754
-0.3072535691850387 -0.01073880122111998 -0.4870359524963758
0.3867462923626847 0.04492879989084675 0.118335500935405
0.3789805913148268 -0.4732086509216658 -0.2177962499836425
rbox 10 D3 | qhull o
3
10 14 21
-0.0222149361131852 -0.366434993563625 0.3270621312102882
-0.06676722137887703 -0.1566931052661437 0.4589771055234383
0.02820502736438535 0.04189077954915421 0.05832764185809314
0.3126723396709863 0.08400649026409401 -0.1029227018383543
0.1781470954214661 0.1182274414396169 0.04860343742054274
-0.1220315663349177 0.01546165115708642 -0.1360330368727754
-0.3072535691850387 -0.01073880122111998 -0.4870359524963758
0.3867462923626847 0.04492879989084675 0.118335500935405
-0.1352406177997967 0.01093378431250691 -0.2358910583293913
0.3789805913148268 -0.4732086509216658 -0.2177962499836425
3 0 9 6
3 1 0 6
3 9 0 7
3 0 1 7
3 9 3 6
3 3 9 7
3 1 4 7
3 4 3 7
3 3 4 6
3 5 1 6
3 4 5 6
3 2 4 1
3 5 2 1
3 2 5 4
rbox 10 D3 | qhull Fx
9
0
1
2
3
4
5
6
7
9
rbox 27 M1,0,1 | qhull Qc
Convex hull of 27 points in 3-d:
Number of vertices: 8
Number of coplanar points: 18
Number of facets: 6
Number of non-simplicial facets: 6
Statistics for: rbox 27 M1,0,1 | qhull Qc
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 320
Number of distance tests for merging: 84
Number of distance tests for checking: 188
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
rbox 50 D3 s | qhull C0.1 Qc Pd0d1d2 s p Tcv
3
7
0.1955434141942995 0.09315491718098735 0.4506494586374647
0.3786694231678469 0.2419725568326128 -0.2192230592287637
0.1164290160865212 0.2250749615572271 0.4310284745734756
0.3010852516984067 0.3425921496145067 0.2048860420629442
0.4995640899182717 0.005583735684776723 0.02011322848106417
0.4035338761538298 0.1419567271683243 0.2588603840063664
0.3642936952899509 -0.2163723184172344 -0.2654677445467591
Convex hull of 50 points in 3-d:
Number of vertices: 19
Number of coplanar points: 31
Number of facets: 12
Number of 'good' facets: 1
Number of 'good' non-simplicial facets: 1
Statistics for: rbox 50 D3 s | qhull C0.1 Qc Pd0d1d2 s p Tcv
Number of points processed: 50
Number of hyperplanes created: 237
Number of distance tests for qhull: 1177
Number of distance tests for merging: 3999
Number of distance tests for checking: 367
Number of merged facets: 84
CPU seconds to compute hull (after input): 0
Maximum distance of vertex below facet: -0.24 (0.8x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 50 distance computations.
rbox 10 D2 P0 P1e-15 | qhull d Qc FP s Tcv
1
0 1 12 1e-015
Delaunay triangulation by the convex hull of 12 points in 3-d:
Number of input sites: 11
Number of nearly incident points: 1
Number of Delaunay regions: 16
Statistics for: rbox 10 D2 P0 P1e-15 | qhull d Qc FP s Tcv
Number of points processed: 11
Number of hyperplanes created: 33
Number of facets in hull: 18
Number of distance tests for qhull: 111
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 192 distance computations.
rbox 100 s | qhull C-0.003 Qc FP s
10
29 92 222 0.05221620842441997
49 2 292 0.03790045221711885
99 9 338 0.02993864679572162
54 84 341 0.06479664045626413
54 72 226 0.03827167959574595
96 6 368 0.02282529175708785
19 1 372 0.01048228658130246
69 26 409 0.04998878658421259
19 66 371 0.008281093788857875
19 45 371 0.04608027722786196
Convex hull of 100 points in 3-d:
Number of vertices: 90
Number of coplanar points: 10
Number of facets: 118
Number of non-simplicial facets: 46
Statistics for: rbox 100 s | qhull C-0.003 Qc FP s
Number of points processed: 90
Number of hyperplanes created: 400
Number of distance tests for qhull: 2016
Number of distance tests for merging: 3695
Number of distance tests for checking: 1469
Number of merged facets: 102
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.0057 (0.6x)
Maximum distance of vertex below facet: -0.0087 (1.0x)
rbox 100 s D2 | qhull C0.1 i Fx Tcv
6
4 28
70 27
77 70
68 4
27 68
28 77
6
4
28
77
70
27
68
Output completed. Verifying that all points are below outer planes of
all facets. Will make 600 distance computations.
rbox 4 s D3 | qhull Qc Ghipv Tcv
{appearance {+edge -evert linewidth 2} LIST # rbox 4 s D3 | qhull Qc Ghipv Tcv
{appearance {-edge -normal normscale 0} {
INST geom {define vsphere OFF
18 32 48
0 0 1
1 0 0
0 1 0
-1 0 0
0 -1 0
0 0 -1
0.707107 0 0.707107
0 -0.707107 0.707107
0.707107 -0.707107 0
-0.707107 0 0.707107
-0.707107 -0.707107 0
0 0.707107 0.707107
-0.707107 0.707107 0
0.707107 0.707107 0
0.707107 0 -0.707107
0 0.707107 -0.707107
-0.707107 0 -0.707107
0 -0.707107 -0.707107
3 0 6 11
3 0 7 6
3 0 9 7
3 0 11 9
3 1 6 8
3 1 8 14
3 1 13 6
3 1 14 13
3 2 11 13
3 2 12 11
3 2 13 15
3 2 15 12
3 3 9 12
3 3 10 9
3 3 12 16
3 3 16 10
3 4 7 10
3 4 8 7
3 4 10 17
3 4 17 8
3 5 14 17
3 5 15 14
3 5 16 15
3 5 17 16
3 6 13 11
3 7 8 6
3 9 10 7
3 11 12 9
3 14 8 17
3 15 13 14
3 16 12 15
3 17 10 16
} transforms { TLIST
0.009951 0 0 0 # v2
0 0.009951 0 0
0 0 0.009951 0
-0.04234 -0.2077 -0.4529 # p3
1
0.009951 0 0 0 # v1
0 0.009951 0 0
0 0 0.009951 0
0.004313 -0.4976 0.04904 # p2
1
0.009951 0 0 0 # v0
0 0.009951 0 0
0 0 0.009951 0
-0.4876 0.03313 -0.1055 # p0
1
0.009951 0 0 0 # v3
0 0.009951 0 0
0 0 0.009951 0
-0.3939 -0.1068 -0.2889 # p1
1
}}}
{ OFF 3 1 1 # f1
-0.04933 -0.2152 -0.4566
-0.002675 -0.5051 0.04532
-0.4946 0.02557 -0.1092
3 0 1 2 0.1808 0.1547 0.3302 1.0 }
VECT 1 2 1 2 1 # intersect f1 f2
0.004313 -0.4976 0.04904 # projected p2
-0.4876 0.03313 -0.1055 # projected p0
0 0 0 1.0
VECT 1 2 1 2 1 # intersect f1 f3
-0.04234 -0.2077 -0.4529 # projected p3
-0.4876 0.03313 -0.1055 # projected p0
0 0 0 1.0
VECT 1 2 1 2 1 # intersect f1 f4
-0.04234 -0.2077 -0.4529 # projected p3
0.004313 -0.4976 0.04904 # projected p2
0 0 0 1.0
{ OFF 3 1 1 # f2
0.01247 -0.4904 0.04773
-0.3857 -0.09961 -0.2902
-0.4795 0.04031 -0.1068
3 0 1 2 0.8726 0.828 0.4402 1.0 }
VECT 1 2 1 2 1 # intersect f2 f3
-0.3939 -0.1068 -0.2889 # projected p1
-0.4876 0.03313 -0.1055 # projected p0
0 0 0 1.0
VECT 1 2 1 2 1 # intersect f2 f4
-0.3939 -0.1068 -0.2889 # projected p1
0.004313 -0.4976 0.04904 # projected p2
0 0 0 1.0
{ OFF 3 1 1 # f3
-0.3931 -0.1153 -0.282
-0.04157 -0.2162 -0.446
-0.4869 0.02464 -0.09863
3 0 1 2 0.5351 0.1123 0.8138 1.0 }
VECT 1 2 1 2 1 # intersect f3 f4
-0.3939 -0.1068 -0.2889 # projected p1
-0.04234 -0.2077 -0.4529 # projected p3
0 0 0 1.0
{ OFF 3 1 1 # f4
-0.03767 -0.1989 -0.4482
-0.3892 -0.09803 -0.2843
0.008983 -0.4888 0.05366
3 0 1 2 0.7133 0.8999 0.7112 1.0 }
}
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 16 distance computations.
rbox 6 D4 | qhull f Tcv
Vertices and facets:
- p3(v4): 0.1 -0.13 -0.17 -0.42
- p0(v3): -0.33 -0.43 -0.46 0.15
- p2(v2): 0.11 0.4 -0.063 -0.18
- p1(v0): -0.35 -0.24 0.14 -0.18
- p4(v1): 0.14 -0.34 -0.084 0.087
- p5(v6): -0.25 -0.5 0.22 -0.033
- f4
- flags: bottom simplicial
- normal: -0.6536 0.3379 -0.424 -0.5281
- offset: -0.1850304
- vertices: p3(v4) p0(v3) p2(v2) p1(v0)
- neighboring facets: f6 f8 f10 f5
- f5
- flags: top simplicial
- normal: 0.6142 0.09488 -0.7743 0.1197
- offset: -0.1313181
- vertices: p3(v4) p0(v3) p2(v2) p4(v1)
- neighboring facets: f7 f9 f11 f4
- f6
- flags: top simplicial
- normal: -0.4209 0.3853 0.2879 0.7691
- offset: 0.04819078
- vertices: p5(v6) p0(v3) p2(v2) p1(v0)
- neighboring facets: f4 f8 f10 f7
- f7
- flags: bottom simplicial
- normal: -0.1759 0.3066 0.2842 0.8912
- offset: 0.07466537
- vertices: p5(v6) p0(v3) p2(v2) p4(v1)
- neighboring facets: f5 f9 f11 f6
- f8
- flags: bottom simplicial
- normal: 0.2584 0.07433 0.814 -0.515
- offset: -0.09844114
- vertices: p5(v6) p3(v4) p2(v2) p1(v0)
- neighboring facets: f4 f6 f10 f9
- f9
- flags: top simplicial
- normal: 0.6576 -0.06072 0.7252 -0.195
- offset: -0.03612816
- vertices: p5(v6) p3(v4) p2(v2) p4(v1)
- neighboring facets: f5 f7 f11 f8
- f10
- flags: top simplicial
- normal: -0.3537 -0.6003 -0.2017 -0.6883
- offset: -0.3651888
- vertices: p5(v6) p3(v4) p0(v3) p1(v0)
- neighboring facets: f4 f6 f8 f11
- f11
- flags: bottom simplicial
- normal: 0.2962 -0.865 -0.2123 -0.3449
- offset: -0.3220787
- vertices: p5(v6) p3(v4) p0(v3) p4(v1)
- neighboring facets: f5 f7 f9 f10
Output completed. Verifying that all points are below 3e-015 of
all facets. Will make 48 distance computations.
rbox 6 D4 | qhull i
8
0 3 2 1
3 0 2 4
5 0 2 1
0 5 2 4
3 5 2 1
5 3 2 4
5 3 0 1
3 5 0 4
rbox 6 D4 | qhull p
4
6
-0.3257826863096865 -0.4296101703584289 -0.4581337649916613 0.1458114577883961
-0.3468340047139991 -0.2391184267952278 0.1365988111464296 -0.1837860440684352
0.1079548672847029 0.397449696341017 -0.062960620096848 -0.1791453880063681
0.1034612661259819 -0.1265049433582509 -0.1685859450777862 -0.4239815160855479
0.1426585555473888 -0.3376619446442108 -0.08430490557505277 0.08744874697872318
-0.2489141260729303 -0.4997188728300099 0.224904344160952 -0.03269336003129686
rbox 6 D4 | qhull o
4
6 8 16
-0.3257826863096865 -0.4296101703584289 -0.4581337649916613 0.1458114577883961
-0.3468340047139991 -0.2391184267952278 0.1365988111464296 -0.1837860440684352
0.1079548672847029 0.397449696341017 -0.062960620096848 -0.1791453880063681
0.1034612661259819 -0.1265049433582509 -0.1685859450777862 -0.4239815160855479
0.1426585555473888 -0.3376619446442108 -0.08430490557505277 0.08744874697872318
-0.2489141260729303 -0.4997188728300099 0.224904344160952 -0.03269336003129686
4 0 3 2 1
4 3 0 2 4
4 5 0 2 1
4 0 5 2 4
4 3 5 2 1
4 5 3 2 4
4 5 3 0 1
4 3 5 0 4
rbox 1000 s D2 | qhull FA Tcv
Convex hull of 1000 points in 2-d:
Number of vertices: 1000
Number of facets: 1000
Statistics for: rbox 1000 s D2 | qhull FA Tcv
Number of points processed: 1000
Number of hyperplanes created: 1998
Number of distance tests for qhull: 13978
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Total facet area: 3.1415592
Total volume: 0.7853647
qhull output completed. Verifying that 1000 points are
below 1.3e-015 of the nearest facet.
rbox 1000 s | qhull FA Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 1000
Number of facets: 1996
Statistics for: rbox 1000 s | qhull FA Tcv
Number of points processed: 1000
Number of hyperplanes created: 5545
Number of distance tests for qhull: 25488
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Total facet area: 3.1201951
Total volume: 0.51650274
qhull output completed. Verifying that 1000 points are
below 2.1e-015 of the nearest facet.
rbox c D4 | qhull FA Tcv
Convex hull of 16 points in 4-d:
Number of vertices: 16
Number of facets: 8
Number of non-simplicial facets: 8
Statistics for: rbox c D4 | qhull FA Tcv
Number of points processed: 16
Number of hyperplanes created: 26
Number of distance tests for qhull: 168
Number of distance tests for merging: 788
Number of distance tests for checking: 144
Number of merged facets: 36
CPU seconds to compute hull (after input): 0
Approximate facet area: 8
Approximate volume: 1
Output completed. Verifying that all points are below outer planes of
all facets. Will make 128 distance computations.
rbox c D5 | qhull FA Tcv
Convex hull of 32 points in 5-d:
Number of vertices: 32
Number of facets: 10
Number of non-simplicial facets: 10
Statistics for: rbox c D5 | qhull FA Tcv
Number of points processed: 32
Number of hyperplanes created: 87
Number of distance tests for qhull: 722
Number of distance tests for merging: 2775
Number of distance tests for checking: 352
Number of merged facets: 210
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Approximate facet area: 10
Approximate volume: 1
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 320 distance computations.
rbox c D5 | qhull FA Qt Tcv
Convex hull of 32 points in 5-d:
Number of vertices: 32
Number of facets: 316
Number of triangulated facets: 10
Statistics for: rbox c D5 | qhull FA Qt Tcv
Number of points processed: 32
Number of hyperplanes created: 87
Number of distance tests for qhull: 722
Number of distance tests for merging: 3235
Number of distance tests for checking: 352
Number of merged facets: 210
CPU seconds to compute hull (after input): 0
Approximate facet area: 10
Approximate volume: 1
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 10112 distance computations.
rbox 10 D2 | qhull d FA Tcv
Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 14
Statistics for: rbox 10 D2 | qhull d FA Tcv
Number of points processed: 10
Number of hyperplanes created: 28
Number of facets in hull: 16
Number of distance tests for qhull: 48
CPU seconds to compute hull (after input): 0
Total facet area: 0.46254269
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull d Qu FA Tcv
Furthest-site Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 2
Statistics for: rbox 10 D2 | qhull d Qu FA Tcv
Number of points processed: 10
Number of hyperplanes created: 28
Number of facets in hull: 16
Number of distance tests for qhull: 48
CPU seconds to compute hull (after input): 0
Total facet area: 0.46254269
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 20 distance computations.
rbox 10 D2 | qhull FA Tcv
Convex hull of 10 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox 10 D2 | qhull FA Tcv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 52
CPU seconds to compute hull (after input): 0
Total facet area: 2.8999576
Total volume: 0.46254269
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 40 distance computations.
rbox 10 c D2 | qhull Fx Tcv
4
10
12
13
11
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 56 distance computations.
rbox 1000 s | qhull FS Tcv
0
2 3.12019513507746 0.516502736886338
qhull output completed. Verifying that 1000 points are
below 2.1e-015 of the nearest facet.
rbox 10 W0 D2 | qhull p Qc FcC Tcv
2
10
-0.3863076515368257 0.5
-0.05259535978789942 0.5
0.2626424396993987 0.5
0.3748708151978168 0.5
-0.01474997775140219 0.5
0.1582814042067914 0.5
-0.5 0.45089279622854
-0.5 -0.003085198815060031
-0.3688616616361418 -0.5
-0.2798755283280048 0.5
5
0
0
0
0
5 2 4 5 9 1
2
5
0.003004576780837498 -8.023127287351645e-018
-0.5 0.22390379870674
-0.4344308308180709 -0.25154259940753
-0.4431538257684129 0.47544639811427
-0.005718418169504469 0.5
Output completed. Verifying that all points are below outer planes of
all facets. Will make 50 distance computations.
rbox 4 z h s D2 | qhull Fd s n FD Tcv
rbox 4 z h s D2 | qhull Fd s n FD Tcv
begin
4 3 real
107643.7343385944 -0.2650304141580589 -0.964240052876465
797791.7732245289 -0.6912673062074456 0.7225991360143615
874890.2679778723 0.9916265954087946 0.1291382796771071
864878.4439653738 0.3984446264475182 0.9171923896626583
end
Convex hull of 4 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox 4 z h s D2 | qhull Fd s n FD Tcv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 5
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.6e-009 of
all facets. Will make 16 distance computations.
rbox 6 s D3 | qhull C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
Vertices and facets:
- p1(v2): -0.3 0.39 -0.092
- p5(v1): 0.4 -0.22 -0.2
- p4(v0): -0.46 -0.19 -0.018
- p2(v3): 0.25 0.28 -0.33
- f1
- flags: top simplicial
- area: 0.26
- normal: 0.2054 0.06987 0.9762
- offset: 0.125398
- center: -0.1205015151724569 -0.008790385787885074 -0.1024776532548504
- vertices: p1(v2) p5(v1) p4(v0)
- neighboring facets: f2 f3 f4
- f2
- flags: bottom simplicial
- area: 0.23
- normal: -0.2032 -0.3001 -0.932
- offset: -0.1680571
- center: 0.06430144219370747 -0.04270356053094847 -0.1805812707066012
- maxoutside: 0.1132672
- coplanar set(furthest p3):
p0: 0.07025 -0.4742 -0.142
p3: 0.2976 -0.2965 -0.2712
furthest distance= 0.11
- vertices: p2(v3) p5(v1) p4(v0)
- neighboring facets: f1 f3 f4
- f3
- flags: top simplicial
- area: 0.18
- normal: -0.3912 -0.01238 -0.9202
- offset: -0.1989549
- center: -0.1715856748140029 0.1590825675964338 -0.1454013928109104
- vertices: p2(v3) p1(v2) p4(v0)
- neighboring facets: f1 f2 f4
- f4
- flags: bottom simplicial
- area: 0.16
- normal: 0.4184 0.3424 0.8413
- offset: 0.07254957
- center: 0.116549362001881 0.1503252206347392 -0.2053893818610149
- vertices: p2(v3) p1(v2) p5(v1)
- neighboring facets: f1 f2 f3
rbox 6 s D3 | qhull C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
4
4
0.205360378770873 0.06987429109559466 0.976188864039624 0.1253980026939646
-0.2031613339148238 -0.3001304507855299 -0.9320124381751694 -0.1680570625036091
-0.3911895500493898 -0.01238286325891905 -0.9202268202077502 -0.1989548866041478
0.4183781509471984 0.3424157187037644 0.8412557271095321 0.07254956874669725
4
4
0.205360378770873 0.06987429109559466 0.976188864039624 0.125398002693964
-0.2031613339148238 -0.3001304507855299 -0.9320124381751694 -0.1680570625036098
-0.3911895500493898 -0.01238286325891905 -0.9202268202077502 -0.1989548866041485
0.4183781509471984 0.3424157187037644 0.8412557271095321 0.0725495687466966
4
4
0.205360378770873 0.06987429109559466 0.976188864039624 0.1253980026939627
-0.2031613339148238 -0.3001304507855299 -0.9320124381751694 -0.2813242952138536
-0.3911895500493898 -0.01238286325891905 -0.9202268202077502 -0.1989548866041498
0.4183781509471984 0.3424157187037644 0.8412557271095321 0.07254956874669528
rbox 6 s D3 | qhull C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
4
1
2
3
4
4
0
0
0
0
4
3 1 2 3
3 0 2 3
3 0 1 3
3 0 1 2
6
1 1
3 3 0 2
3 3 1 2
1 1
3 2 0 1
3 3 0 1
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315281981 Centrum-premerge- 0.1 Qcoplanar-keep FFacets-xridge
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510094292 Centrum-premerge- 0.1 Qcoplanar-keep FFacets-xridge
summary FQhull Finner normals Fouter FQhull FIDs Fmerges Fneighbors
FNeighbors-vertex FOptions FQhull Fsummary FSize FVertex-average
Tcheck-frequently Tverify Fvertices _max-width 0.86
Error-roundoff 6.6e-016 _one-merge 0.3 _near-inside 1.5
Visible-distance 0.1 U-coplanar-distance 0.1 Width-outside 0.2
_wide-facet 0.6
rbox 6 s D3 | qhull C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
10 3 6 4 4 4 4 2 0 0 0
2 0.1132672327102437 -1.315898280434284e-015
0
2 0.8296676646636063 0.01051107893821417
3 1
-0.02780909644771785 0.06447846047808484 -0.1584624246583442
4
3 1 5 4
3 2 5 4
3 2 1 4
3 2 1 5
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315281981 Centrum-premerge- 0.1 Qcoplanar-keep FFacets-xridge
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510094292 Centrum-premerge- 0.1 Qcoplanar-keep FFacets-xridge
summary FQhull Finner normals Fouter FQhull FIDs Fmerges Fneighbors
FNeighbors-vertex FOptions FQhull Fsummary FSize FVertex-average
Tcheck-frequently Tverify Fvertices _max-width 0.86
Error-roundoff 6.6e-016 _one-merge 0.3 _near-inside 1.5
Visible-distance 0.1 U-coplanar-distance 0.1 Width-outside 0.2
_wide-facet 0.6
Convex hull of 6 points in 3-d:
Number of vertices: 4
Number of coplanar points: 2
Number of facets: 4
Statistics for: rbox 6 s D3 | qhull C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
Number of points processed: 4
Number of hyperplanes created: 5
Number of distance tests for qhull: 24
CPU seconds to compute hull (after input): 0
Total facet area: 0.82966766
Total volume: 0.010511079
Maximum distance of point above facet: 0.11 (0.4x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 24 distance computations.
rbox P0.5,0.5 P0.5,0.5 W0 5 D2 | qhull d FN Qc
7
5 3 0 2 -7 -8
1 0
5 -10 1 -6 -7 -8
4 -6 1 0 2
3 -7 2 -6
3 -10 -8 3
4 -10 1 0 3
rbox 10 D3 | qhull Fa PA5
5
0.2844546842397038
0.1170134053930415
0.1758021655943633
0.07490600482805046
0.2087585943133527
rbox 10 D3 | qhull Fa PF0.4
0
QH7055 qhull warning: no facets printed
echo === test Qt ${d:-`date`}
date
-=== test Qt Tue Jan 24 20:16:50 EST 2012
+=== test Qt Sun Aug 30 22:24:33 EDT 2015
rbox c | qhull Qt s o Tcv
3
8 12 18
-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
3 6 2 0
3 4 6 0
3 5 4 0
3 1 5 0
3 5 6 4
3 6 5 7
3 2 3 0
3 3 1 0
3 6 3 2
3 3 6 7
3 3 5 1
3 5 3 7
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 12
Number of triangulated facets: 6
Statistics for: rbox c | qhull Qt s o Tcv
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 166
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96 distance computations.
rbox c | qhull Qt f i
Vertices and facets:
- p6(v6): 0.5 0.5 -0.5
neighbors: f17 f18 f25 f27 f33 f34
- p2(v2): -0.5 0.5 -0.5
neighbors: f17 f29 f33
- p0(v0): -0.5 -0.5 -0.5
neighbors: f17 f18 f21 f22 f29 f30
- p4(v1): 0.5 -0.5 -0.5
neighbors: f18 f21 f25
- p5(v7): 0.5 -0.5 0.5
neighbors: f21 f22 f25 f27 f37 f38
- p1(v3): -0.5 -0.5 0.5
neighbors: f22 f30 f37
- p7(v5): 0.5 0.5 0.5
neighbors: f27 f34 f38
- p3(v8): -0.5 0.5 0.5
neighbors: f29 f30 f33 f34 f37 f38
- f17
- flags: top simplicial tricoplanar seen keepcentrum
- owner of normal & centrum is facet f17
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- vertices: p6(v6) p2(v2) p0(v0)
- neighboring facets: f29 f18 f33
- f18
- flags: bottom simplicial tricoplanar seen
- owner of normal & centrum is facet f17
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- vertices: p6(v6) p4(v1) p0(v0)
- neighboring facets: f21 f17 f25
- f21
- flags: top simplicial tricoplanar keepcentrum
- owner of normal & centrum is facet f21
- normal: 0 -1 0
- offset: -0.5
- center: 0 -0.5 0
- vertices: p5(v7) p4(v1) p0(v0)
- neighboring facets: f18 f22 f25
- f22
- flags: bottom simplicial tricoplanar seen
- owner of normal & centrum is facet f21
- normal: 0 -1 0
- offset: -0.5
- center: 0 -0.5 0
- vertices: p5(v7) p1(v3) p0(v0)
- neighboring facets: f30 f21 f37
- f25
- flags: top simplicial tricoplanar keepcentrum
- owner of normal & centrum is facet f25
- normal: 1 -0 -0
- offset: -0.5
- center: 0.5 0 0
- vertices: p5(v7) p6(v6) p4(v1)
- neighboring facets: f18 f21 f27
- f27
- flags: bottom simplicial tricoplanar seen
- owner of normal & centrum is facet f25
- normal: 1 -0 -0
- offset: -0.5
- center: 0.5 0 0
- vertices: p5(v7) p6(v6) p7(v5)
- neighboring facets: f34 f38 f25
- f29
- flags: bottom simplicial tricoplanar keepcentrum
- owner of normal & centrum is facet f29
- normal: -1 -0 -0
- offset: -0.5
- center: -0.5 0 0
- vertices: p3(v8) p2(v2) p0(v0)
- neighboring facets: f17 f30 f33
- f30
- flags: top simplicial tricoplanar
- owner of normal & centrum is facet f29
- normal: -1 -0 -0
- offset: -0.5
- center: -0.5 0 0
- vertices: p3(v8) p1(v3) p0(v0)
- neighboring facets: f22 f29 f37
- f33
- flags: bottom simplicial tricoplanar keepcentrum
- owner of normal & centrum is facet f33
- normal: 0 1 -0
- offset: -0.5
- center: 0 0.5 0
- vertices: p3(v8) p6(v6) p2(v2)
- neighboring facets: f17 f29 f34
- f34
- flags: top simplicial tricoplanar
- owner of normal & centrum is facet f33
- normal: 0 1 -0
- offset: -0.5
- center: 0 0.5 0
- vertices: p3(v8) p6(v6) p7(v5)
- neighboring facets: f27 f38 f33
- f37
- flags: top simplicial tricoplanar keepcentrum
- owner of normal & centrum is facet f37
- normal: -0 -0 1
- offset: -0.5
- center: 0 0 0.5
- vertices: p3(v8) p5(v7) p1(v3)
- neighboring facets: f22 f30 f38
- f38
- flags: bottom simplicial tricoplanar
- owner of normal & centrum is facet f37
- normal: -0 -0 1
- offset: -0.5
- center: 0 0 0.5
- vertices: p3(v8) p5(v7) p7(v5)
- neighboring facets: f27 f34 f37
12
6 2 0
4 6 0
5 4 0
1 5 0
5 6 4
6 5 7
2 3 0
3 1 0
6 3 2
3 6 7
3 5 1
5 3 7
rbox c | qhull Qt m FM n
{
Polygon[{{ 0.50000000, 0.50000000, -0.50000000},
{ -0.50000000, 0.50000000, -0.50000000},
{ -0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ 0.50000000, -0.50000000, -0.50000000},
{ 0.50000000, 0.50000000, -0.50000000},
{ -0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ 0.50000000, -0.50000000, 0.50000000},
{ 0.50000000, -0.50000000, -0.50000000},
{ -0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ -0.50000000, -0.50000000, 0.50000000},
{ 0.50000000, -0.50000000, 0.50000000},
{ -0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ 0.50000000, -0.50000000, 0.50000000},
{ 0.50000000, 0.50000000, -0.50000000},
{ 0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ 0.50000000, 0.50000000, -0.50000000},
{ 0.50000000, -0.50000000, 0.50000000},
{ 0.50000000, 0.50000000, 0.50000000}}],
Polygon[{{ -0.50000000, 0.50000000, -0.50000000},
{ -0.50000000, 0.50000000, 0.50000000},
{ -0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ -0.50000000, 0.50000000, 0.50000000},
{ -0.50000000, -0.50000000, 0.50000000},
{ -0.50000000, -0.50000000, -0.50000000}}],
Polygon[{{ 0.50000000, 0.50000000, -0.50000000},
{ -0.50000000, 0.50000000, 0.50000000},
{ -0.50000000, 0.50000000, -0.50000000}}],
Polygon[{{ -0.50000000, 0.50000000, 0.50000000},
{ 0.50000000, 0.50000000, -0.50000000},
{ 0.50000000, 0.50000000, 0.50000000}}],
Polygon[{{ -0.50000000, 0.50000000, 0.50000000},
{ 0.50000000, -0.50000000, 0.50000000},
{ -0.50000000, -0.50000000, 0.50000000}}],
Polygon[{{ 0.50000000, -0.50000000, 0.50000000},
{ -0.50000000, 0.50000000, 0.50000000},
{ 0.50000000, 0.50000000, 0.50000000}}]}
PLOT3D(POLYGONS(
[[ 0.50000000, 0.50000000, -0.50000000],
[ -0.50000000, 0.50000000, -0.50000000],
[ -0.50000000, -0.50000000, -0.50000000]],
[[ 0.50000000, -0.50000000, -0.50000000],
[ 0.50000000, 0.50000000, -0.50000000],
[ -0.50000000, -0.50000000, -0.50000000]],
[[ 0.50000000, -0.50000000, 0.50000000],
[ 0.50000000, -0.50000000, -0.50000000],
[ -0.50000000, -0.50000000, -0.50000000]],
[[ -0.50000000, -0.50000000, 0.50000000],
[ 0.50000000, -0.50000000, 0.50000000],
[ -0.50000000, -0.50000000, -0.50000000]],
[[ 0.50000000, -0.50000000, 0.50000000],
[ 0.50000000, 0.50000000, -0.50000000],
[ 0.50000000, -0.50000000, -0.50000000]],
[[ 0.50000000, 0.50000000, -0.50000000],
[ 0.50000000, -0.50000000, 0.50000000],
[ 0.50000000, 0.50000000, 0.50000000]],
[[ -0.50000000, 0.50000000, -0.50000000],
[ -0.50000000, 0.50000000, 0.50000000],
[ -0.50000000, -0.50000000, -0.50000000]],
[[ -0.50000000, 0.50000000, 0.50000000],
[ -0.50000000, -0.50000000, 0.50000000],
[ -0.50000000, -0.50000000, -0.50000000]],
[[ 0.50000000, 0.50000000, -0.50000000],
[ -0.50000000, 0.50000000, 0.50000000],
[ -0.50000000, 0.50000000, -0.50000000]],
[[ -0.50000000, 0.50000000, 0.50000000],
[ 0.50000000, 0.50000000, -0.50000000],
[ 0.50000000, 0.50000000, 0.50000000]],
[[ -0.50000000, 0.50000000, 0.50000000],
[ 0.50000000, -0.50000000, 0.50000000],
[ -0.50000000, -0.50000000, 0.50000000]],
[[ 0.50000000, -0.50000000, 0.50000000],
[ -0.50000000, 0.50000000, 0.50000000],
[ 0.50000000, 0.50000000, 0.50000000]]));
4
12
-0 -0 -1 -0.5
-0 -0 -1 -0.5
0 -1 0 -0.5
0 -1 0 -0.5
1 -0 -0 -0.5
1 -0 -0 -0.5
-1 -0 -0 -0.5
-1 -0 -0 -0.5
0 1 -0 -0.5
0 1 -0 -0.5
-0 -0 1 -0.5
-0 -0 1 -0.5
rbox c | qhull Qt p o
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
3
8 12 18
-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
3 6 2 0
3 4 6 0
3 5 4 0
3 1 5 0
3 5 6 4
3 6 5 7
3 2 3 0
3 3 1 0
3 6 3 2
3 3 6 7
3 3 5 1
3 5 3 7
rbox c | qhull Qt Fx
8
0
1
2
3
4
5
6
7
rbox c | qhull Qt FA s Fa
12
0.5
0.5
0.5
0.5
0.5
0.5
0.5
0.5
0.5
0.5
0.5
0.5
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 12
Number of triangulated facets: 6
Statistics for: rbox c | qhull Qt FA s Fa
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 108
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Approximate facet area: 6
Approximate volume: 1
rbox 6 r s c G0.1 D2 | qhull Qt d FA Tcv
Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 12
Number of triangulated facets: 3
Statistics for: rbox 6 r s c G0.1 D2 | qhull Qt d FA Tcv
Number of points processed: 10
Number of hyperplanes created: 20
Number of facets in hull: 16
Number of distance tests for qhull: 51
Number of distance tests for merging: 257
Number of distance tests for checking: 100
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
Approximate facet area: 0.64951905
Output completed. Verifying that all points are below outer planes of
all facets. Will make 120 distance computations.
rbox 6 r s c G0.1 D2 | qhull d FA Tcv
Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 9
Number of non-simplicial Delaunay regions: 3
Statistics for: rbox 6 r s c G0.1 D2 | qhull d FA Tcv
Number of points processed: 10
Number of hyperplanes created: 20
Number of facets in hull: 10
Number of distance tests for qhull: 51
Number of distance tests for merging: 239
Number of distance tests for checking: 100
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
Approximate facet area: 0.64951905
Output completed. Verifying that all points are below outer planes of
all facets. Will make 90 distance computations.
rbox 6 r s c G0.1 D2 | qhull Qt v p Tcv
2
12
-0.3359969878447703 -0.1939879513790814
-0.3359969878447704 0.1939879513790817
-0.2875 0
0.3359969878447702 -0.1939879513790819
0.3359969878447707 0.1939879513790815
0.2875 0
-2.220446049250313e-016 -0.3453321730569308
-2.220446049250313e-016 -0.3453321730569308
1.110223024625157e-016 0.3453321730569308
1.110223024625157e-016 0.3453321730569308
0 0
0 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 120 distance computations.
rbox c | qhull Qt C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
Vertices and facets:
- p6(v6): 0.5 0.5 -0.5
neighbors: f17 f18 f25 f27 f33 f34
- p2(v2): -0.5 0.5 -0.5
neighbors: f17 f29 f33
- p0(v0): -0.5 -0.5 -0.5
neighbors: f17 f18 f21 f22 f29 f30
- p4(v1): 0.5 -0.5 -0.5
neighbors: f18 f21 f25
- p5(v7): 0.5 -0.5 0.5
neighbors: f21 f22 f25 f27 f37 f38
- p1(v3): -0.5 -0.5 0.5
neighbors: f22 f30 f37
- p7(v5): 0.5 0.5 0.5
neighbors: f27 f34 f38
- p3(v8): -0.5 0.5 0.5
neighbors: f29 f30 f33 f34 f37 f38
- f17
- flags: top simplicial tricoplanar keepcentrum
- area: 0.5
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- vertices: p6(v6) p2(v2) p0(v0)
- neighboring facets: f29 f18 f33
- f18
- flags: bottom simplicial tricoplanar
- area: 0.5
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- vertices: p6(v6) p4(v1) p0(v0)
- neighboring facets: f21 f17 f25
- f21
- flags: top simplicial tricoplanar keepcentrum
- area: 0.5
- normal: 0 -1 0
- offset: -0.5
- center: 0 -0.5 0
- vertices: p5(v7) p4(v1) p0(v0)
- neighboring facets: f18 f22 f25
- f22
- flags: bottom simplicial tricoplanar
- area: 0.5
- normal: 0 -1 0
- offset: -0.5
- center: 0 -0.5 0
- vertices: p5(v7) p1(v3) p0(v0)
- neighboring facets: f30 f21 f37
- f25
- flags: top simplicial tricoplanar keepcentrum
- area: 0.5
- normal: 1 -0 -0
- offset: -0.5
- center: 0.5 0 0
- vertices: p5(v7) p6(v6) p4(v1)
- neighboring facets: f18 f21 f27
- f27
- flags: bottom simplicial tricoplanar
- area: 0.5
- normal: 1 -0 -0
- offset: -0.5
- center: 0.5 0 0
- vertices: p5(v7) p6(v6) p7(v5)
- neighboring facets: f34 f38 f25
- f29
- flags: bottom simplicial tricoplanar keepcentrum
- area: 0.5
- normal: -1 -0 -0
- offset: -0.5
- center: -0.5 0 0
- vertices: p3(v8) p2(v2) p0(v0)
- neighboring facets: f17 f30 f33
- f30
- flags: top simplicial tricoplanar
- area: 0.5
- normal: -1 -0 -0
- offset: -0.5
- center: -0.5 0 0
- vertices: p3(v8) p1(v3) p0(v0)
- neighboring facets: f22 f29 f37
- f33
- flags: bottom simplicial tricoplanar keepcentrum
- area: 0.5
- normal: 0 1 -0
- offset: -0.5
- center: 0 0.5 0
- vertices: p3(v8) p6(v6) p2(v2)
- neighboring facets: f17 f29 f34
- f34
- flags: top simplicial tricoplanar
- area: 0.5
- normal: 0 1 -0
- offset: -0.5
- center: 0 0.5 0
- vertices: p3(v8) p6(v6) p7(v5)
- neighboring facets: f27 f38 f33
- f37
- flags: top simplicial tricoplanar keepcentrum
- area: 0.5
- normal: -0 -0 1
- offset: -0.5
- center: 0 0 0.5
- vertices: p3(v8) p5(v7) p1(v3)
- neighboring facets: f22 f30 f38
- f38
- flags: bottom simplicial tricoplanar
- area: 0.5
- normal: -0 -0 1
- offset: -0.5
- center: 0 0 0.5
- vertices: p3(v8) p5(v7) p7(v5)
- neighboring facets: f27 f34 f37
rbox c | qhull Qt C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
4
12
-0 -0 -1 -0.4999999999999993
-0 -0 -1 -0.4999999999999993
0 -1 0 -0.4999999999999993
0 -1 0 -0.4999999999999993
1 -0 -0 -0.4999999999999993
1 -0 -0 -0.4999999999999993
-1 -0 -0 -0.4999999999999993
-1 -0 -0 -0.4999999999999993
0 1 -0 -0.4999999999999993
0 1 -0 -0.4999999999999993
-0 -0 1 -0.4999999999999993
-0 -0 1 -0.4999999999999993
4
12
-0 -0 -1 -0.5
-0 -0 -1 -0.5
0 -1 0 -0.5
0 -1 0 -0.5
1 -0 -0 -0.5
1 -0 -0 -0.5
-1 -0 -0 -0.5
-1 -0 -0 -0.5
0 1 -0 -0.5
0 1 -0 -0.5
-0 -0 1 -0.5
-0 -0 1 -0.5
4
12
-0 -0 -1 -0.5000000000000013
-0 -0 -1 -0.5000000000000013
0 -1 0 -0.5000000000000013
0 -1 0 -0.5000000000000013
1 -0 -0 -0.5000000000000013
1 -0 -0 -0.5000000000000013
-1 -0 -0 -0.5000000000000013
-1 -0 -0 -0.5000000000000013
0 1 -0 -0.5000000000000013
0 1 -0 -0.5000000000000013
-0 -0 1 -0.5000000000000013
-0 -0 1 -0.5000000000000013
rbox c | qhull Qt C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
12
17
18
21
22
25
27
29
30
33
34
37
38
12
0
0
0
0
0
0
0
0
0
0
0
0
12
3 6 1 8
3 2 0 4
3 1 3 4
3 7 2 10
3 1 2 5
3 9 11 4
3 0 7 8
3 3 6 10
3 0 6 9
3 5 11 8
3 3 7 11
3 5 9 10
8
6 7 3 2 1 0 6
3 10 3 7
3 8 0 6
6 11 9 8 6 7 10
3 4 1 2
6 11 5 4 2 3 10
6 9 5 4 1 0 8
3 11 5 9
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315298788 Qtriangulate Centrum-premerge- 0.1 Qcoplanar-keep
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510111099 Qtriangulate Centrum-premerge- 0.1 Qcoplanar-keep
FFacets-xridge summary FQhull Finner normals Fouter FQhull FIDs
Fmerges Fneighbors FNeighbors-vertex FOptions FQhull Fsummary FSize
FVertex-average Tcheck-frequently Tverify Fvertices _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.3 _near-inside 1.5
Visible-distance 0.1 U-coplanar-distance 0.1 Width-outside 0.2
_wide-facet 0.6
rbox c | qhull Qt C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
10 3 8 8 12 8 12 0 0 0 6
2 1.387359992873471e-015 -6.936799964367356e-016
0
2 6 1
3 1
0 0 0
12
3 6 2 0
3 6 4 0
3 5 4 0
3 5 1 0
3 5 6 4
3 5 6 7
3 3 2 0
3 3 1 0
3 3 6 2
3 3 6 7
3 3 5 1
3 3 5 7
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315298788 Qtriangulate Centrum-premerge- 0.1 Qcoplanar-keep
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510111099 Qtriangulate Centrum-premerge- 0.1 Qcoplanar-keep
FFacets-xridge summary FQhull Finner normals Fouter FQhull FIDs
Fmerges Fneighbors FNeighbors-vertex FOptions FQhull Fsummary FSize
FVertex-average Tcheck-frequently Tverify Fvertices _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.3 _near-inside 1.5
Visible-distance 0.1 U-coplanar-distance 0.1 Width-outside 0.2
_wide-facet 0.6
Convex hull of 8 points in 3-d:
Number of vertices: 8
Number of facets: 12
Number of triangulated facets: 6
Statistics for: rbox c | qhull Qt C-0.1 Qc FF s FQ Fi n Fo FQ FI Fm Fn FN FO FO FQ Fs FS FV Fv Tcv
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 198
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
Approximate facet area: 6
Approximate volume: 1
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96 distance computations.
rbox 6 r s c G0.1 D2 P0.1,0.1 | qhull s FP d FO Qt
1
0 10 36 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315298788 summary FPoint-nearest delaunay Qtriangulate _pre-merge
- _zero-centrum Pgood Qcoplanar _max-width 1 Error-roundoff 6.9e-016
- _one-merge 4.9e-015 _near-inside 2.4e-014 Visible-distance 1.4e-015
- U-coplanar-distance 1.4e-015 Width-outside 2.8e-015 _wide-facet 8.3e-015
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510111099 summary FPoint-nearest delaunay Qtriangulate
+ _pre-merge _zero-centrum Pgood Qcoplanar _max-width 1
+ Error-roundoff 6.9e-016 _one-merge 4.9e-015 _near-inside 2.4e-014
+ Visible-distance 1.4e-015 U-coplanar-distance 1.4e-015
+ Width-outside 2.8e-015 _wide-facet 8.3e-015
Delaunay triangulation by the convex hull of 11 points in 3-d:
Number of input sites: 10
Number of nearly incident points: 1
Number of Delaunay regions: 12
Number of triangulated facets: 3
Statistics for: rbox 6 r s c G0.1 D2 P0.1,0.1 | qhull s FP d FO Qt
Number of points processed: 10
Number of hyperplanes created: 20
Number of facets in hull: 16
Number of distance tests for qhull: 83
Number of distance tests for merging: 166
Number of distance tests for checking: 111
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
rbox 100 W0 | qhull Tv Q11
Convex hull of 100 points in 3-d:
Number of vertices: 45
Number of facets: 86
Number of triangulated facets: 33
Statistics for: rbox 100 W0 | qhull Tv Q11
Number of points processed: 52
Number of hyperplanes created: 172
Number of distance tests for qhull: 1576
Number of distance tests for merging: 1498
Number of distance tests for checking: 2172
Number of merged facets: 41
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 8600 distance computations.
echo === test unbounded intersection ${d:-`date`}
date
-=== test unbounded intersection Tue Jan 24 20:16:50 EST 2012
+=== test unbounded intersection Sun Aug 30 22:24:34 EDT 2015
rbox c | qhull PD0:0.5 n | qhull H0 Fp Tcv
3
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
-10.101 -10.101 -10.101
Output completed. Verifying that all points are below outer planes of
all facets. Will make 25 distance computations.
rbox 1000 W1e-3 D3 | qhull PA8 Fa FS s n Tcv
8
0.1446087232094601
0.1622198334884075
0.2057158590759609
0.1567143851824352
0.188985866819172
0.1580674614313253
0.1616733826473112
0.1767351337533958
0
2 5.881743214947514 0.9968516315221345
4
8
1.009144997325421e-005 0.9999999999463923 2.319049754624652e-006 -0.4999875785488853
-1.229609861584452e-005 8.587946880918045e-005 0.9999999962367613 -0.500004859549355
-1.383340239672453e-005 -0.9999999998842694 6.332306547224587e-006 -0.4999917156571327
1.802476239613105e-005 -1.901476191096464e-005 0.9999999996567733 -0.4999909156385879
0.9999999996788914 1.780140020603311e-005 -1.803683546259361e-005 -0.4999971349013697
3.470111681088057e-006 -3.668365732095583e-005 -0.9999999993211337 -0.4999893476858696
-1.633273154317779e-005 -0.9999999998072314 1.089857916466569e-005 -0.4999921708899001
-0.9999999997878146 -2.055073083002867e-005 -1.427680287414111e-006 -0.4999990322171606
Convex hull of 1000 points in 3-d:
Number of vertices: 156
Number of facets: 308
Number of 'good' facets: 8
Statistics for: rbox 1000 W1e-3 D3 | qhull PA8 Fa FS s n Tcv
Number of points processed: 203
Number of hyperplanes created: 1043
Number of distance tests for qhull: 21470
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
Total facet area: 5.8817432
Total volume: 0.99685163
Output completed. Verifying that all points are below outer planes of
all facets. Will make 8000 distance computations.
rbox 1000 W1e-3 D3 | qhull C-0.01 PM10 Fm n Tcv Qc
10
1
1
8
0
6
7
10
0
11
6
4
10
0.6345454980886096 0.2737427089707436 0.7227841587506171 -0.7458921924784656
-0.00253733560834815 0.666653414016696 0.7453635270845322 -0.6767722083805112
-0.0004022623770974538 0.9999997831336711 0.0005214571799133833 -0.5000167453415887
-0.5357402012449896 -0.5359428531021374 -0.6524934443952053 -0.811263040246498
-0.005480509661076106 -0.9999701072857251 0.005454223027194167 -0.4992904789191579
0.001196850675493193 0.0003334814784797861 0.9999992281689842 -0.4989807987213126
0.9999992961453315 0.00118637926097064 1.459763172590229e-005 -0.4998611663332402
-0.9129791746952519 0.1462545158779729 -0.3808919048208773 -0.6797481567213483
-0.999601787347817 0.02140818392627282 0.01838359029211947 -0.4985486000821886
-0.003237401631533091 0.002761552371517554 -0.9999909464886048 -0.4969398742962436
Output completed. Verifying that all points are below outer planes of
all facets. Will make 10000 distance computations.
rbox 1000 W1e-3 D3 | qhull C-0.01 PA8 PG n Tcv Qc
4
11
0.6345454980886096 0.2737427089707436 0.7227841587506171 -0.7458921924784656
0.8278306348810541 -0.3414688798813042 -0.4450791435520636 -0.7665474225756105
0.7383776593319754 -0.4655216164679658 0.4879426777814023 -0.7788991125303444
0.2008161614085187 -0.8823413491644904 0.425613219803773 -0.6982307124493008
-0.4745617604911457 -0.2935495843214587 0.8298311738084099 -0.7523676152838523
-0.8259135249806853 -0.559220008247317 0.07169261907511661 -0.6812000445406896
0.41932306725662 0.6721295192910486 -0.6102541065524131 -0.7755692997856908
-0.5357402012449896 -0.5359428531021374 -0.6524934443952053 -0.811263040246498
-0.3304054030140146 0.4364026747636864 -0.8368900615482577 -0.7495022949733237
0.6755431502353132 -0.2163920762108173 0.7048517017950092 -0.7475007704997935
-0.9129791746952519 0.1462545158779729 -0.3808919048208773 -0.6797481567213483
Output completed. Verifying that all points are below outer planes of
all facets. Will make 8000 distance computations.
rbox 10 | qhull FO Tz TO q_test.log.1
cat q_test.log.1
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315298788 Tz-stdout TOutput-file q_test.log.1 _pre-merge
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510111099 Tz-stdout TOutput-file q_test.log.1 _pre-merge
_zero-centrum _max-width 0.92 Error-roundoff 6.8e-016 _one-merge 4.8e-015
_near-inside 2.4e-014 Visible-distance 1.4e-015
U-coplanar-distance 1.4e-015 Width-outside 2.7e-015 _wide-facet 8.2e-015
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 | qhull FO Tz TO q_test.log.1
Number of points processed: 10
Number of hyperplanes created: 27
Number of distance tests for qhull: 44
CPU seconds to compute hull (after input): 0
echo === check Delaunay/Voronoi ${d:-`date`}
date
-=== check Delaunay/Voronoi Tue Jan 24 20:16:50 EST 2012
+=== check Delaunay/Voronoi Sun Aug 30 22:24:34 EDT 2015
rbox 10 D2 | qhull d Tcv
Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 14
Statistics for: rbox 10 D2 | qhull d Tcv
Number of points processed: 10
Number of hyperplanes created: 28
Number of facets in hull: 16
Number of distance tests for qhull: 48
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull d Tcv Qz
Delaunay triangulation by the convex hull of 11 points in 3-d:
Number of input sites and at-infinity: 11
Number of Delaunay regions: 14
Statistics for: rbox 10 D2 | qhull d Tcv Qz
Number of points processed: 11
Number of hyperplanes created: 31
Number of facets in hull: 18
Number of distance tests for qhull: 56
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 154 distance computations.
rbox 10 D3 | qhull d Tcv
Delaunay triangulation by the convex hull of 10 points in 4-d:
Number of input sites: 10
Number of Delaunay regions: 18
Statistics for: rbox 10 D3 | qhull d Tcv
Number of points processed: 10
Number of hyperplanes created: 44
Number of facets in hull: 27
Number of distance tests for qhull: 67
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 180 distance computations.
rbox c | qhull d Qz Ft Tcv
3
10 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 0 0
0 0 0
4 9 1 2 0
4 9 2 4 0
4 9 4 1 0
4 9 5 7 1
4 9 7 6 2
4 9 2 6 4
4 9 6 7 4
4 9 5 1 4
4 9 7 5 4
4 9 1 3 2
4 9 3 7 2
4 9 7 3 1
Output completed. Verifying that all points are below outer planes of
all facets. Will make 9 distance computations.
rbox 10 s D2 c | qhull d Tcv
Delaunay triangulation by the convex hull of 14 points in 3-d:
Number of input sites: 14
Number of Delaunay regions: 15
Number of non-simplicial Delaunay regions: 1
Statistics for: rbox 10 s D2 c | qhull d Tcv
Number of points processed: 14
Number of hyperplanes created: 33
Number of facets in hull: 16
Number of distance tests for qhull: 116
Number of distance tests for merging: 395
Number of distance tests for checking: 182
Number of merged facets: 8
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 210 distance computations.
rbox 10 s D2 | qhull d Tcv Q8 Qz
Delaunay triangulation by the convex hull of 11 points in 3-d:
Number of input sites and at-infinity: 11
Number of Delaunay regions: 1
Number of non-simplicial Delaunay regions: 1
Statistics for: rbox 10 s D2 | qhull d Tcv Q8 Qz
Number of points processed: 11
Number of hyperplanes created: 19
Number of facets in hull: 11
Number of distance tests for qhull: 55
Number of distance tests for merging: 278
Number of distance tests for checking: 132
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
QH7077 qhull input warning: no outer plane check ('Q5') or no processing of
near-inside points ('Q8'). Verify may report that a point is outside
of a facet.
Output completed. Verifying that all points are below outer planes of
all facets. Will make 11 distance computations.
rbox 10 D2 | qhull d Tcv p
3
10
-0.02222276248244826 -0.4979727817680433 0.2484707425541546
-0.4285431913366012 0.4745826469497594 0.4088779556267987
0.3105396575392593 0.2400179190933871 0.1540434803905201
-0.01883958887200765 0.3630260628303755 0.13214285240299
0.3790312361708201 0.3779794437605696 0.2865331378987296
-0.2994955874043476 0.3776609263174803 0.2323253821416526
0.3471817493878135 0.08365533089605659 0.1275333814953112
-0.00485819764887746 0.3482682405489201 0.121314369459436
0.3443122672329771 -0.1437312230875075 0.1392096018573439
0.309330780347186 -0.07758103877080702 0.1017043492469565
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull d Tcv i
14
9 7 0
8 9 0
3 4 1
3 7 4
7 2 4
0 5 1
7 5 0
5 3 1
3 5 7
6 7 9
6 2 7
8 6 9
6 8 4
2 6 4
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull d Tcv o
3
10 14 21
-0.02222276248244826 -0.4979727817680433 0.2484707425541546
-0.4285431913366012 0.4745826469497594 0.4088779556267987
0.3105396575392593 0.2400179190933871 0.1540434803905201
-0.01883958887200765 0.3630260628303755 0.13214285240299
0.3790312361708201 0.3779794437605696 0.2865331378987296
-0.2994955874043476 0.3776609263174803 0.2323253821416526
0.3471817493878135 0.08365533089605659 0.1275333814953112
-0.00485819764887746 0.3482682405489201 0.121314369459436
0.3443122672329771 -0.1437312230875075 0.1392096018573439
0.309330780347186 -0.07758103877080702 0.1017043492469565
3 9 7 0
3 8 9 0
3 3 4 1
3 3 7 4
3 7 2 4
3 0 5 1
3 7 5 0
3 5 3 1
3 3 5 7
3 6 7 9
3 6 2 7
3 8 6 9
3 6 8 4
3 2 6 4
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Tcv o
2
15 10 1
-10.101 -10.101
-0.1294381801544404 -0.07247409101984714
0.08267689532419748 -0.2397644955865706
0.1295260566906465 1.716033573116838
0.1740355150742391 0.5317519038435655
0.1851415205797575 0.3882545794457364
-0.9065939866848107 -0.2962957610652136
-0.1954805620516266 -0.07111892482963184
-0.1407581310832468 0.7233857048236082
-0.1676297826663962 0.2080621273999375
0.05868313821742954 0.06632066014880154
0.08806341399736994 0.1054080604689985
0.4761588899009253 -0.03168366595227294
3.094213357897477 -0.064721945677682
0.5410515627308725 0.211561543495592
5 7 1 2 0 6
4 8 3 0 6
3 14 5 11
4 9 4 3 8
6 14 5 4 3 0 13
4 9 7 6 8
5 14 11 10 12 13
7 11 5 4 9 7 1 10
4 13 0 2 12
4 12 2 1 10
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Tcv p
2
14
-0.1294381801544404 -0.07247409101984714
0.08267689532419748 -0.2397644955865706
0.1295260566906465 1.716033573116838
0.1740355150742391 0.5317519038435655
0.1851415205797575 0.3882545794457364
-0.9065939866848107 -0.2962957610652136
-0.1954805620516266 -0.07111892482963184
-0.1407581310832468 0.7233857048236082
-0.1676297826663962 0.2080621273999375
0.05868313821742954 0.06632066014880154
0.08806341399736994 0.1054080604689985
0.4761588899009253 -0.03168366595227294
3.094213357897477 -0.064721945677682
0.5410515627308725 0.211561543495592
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Tcv G
{appearance {linewidth 3} LIST # rbox 10 D2 | qhull v Tcv G
{appearance {+edge -face} OFF 15 10 1 # Voronoi centers and cells
0 0 0 # infinity not used
# 1 f8
-0.1294381801544404 -0.07247409101984714 0
# 2 f11
0.08267689532419748 -0.2397644955865706 0
# 3 f12
0.1295260566906465 1.716033573116838 0
# 4 f14
0.1740355150742391 0.5317519038435655 0
# 5 f15
0.1851415205797575 0.3882545794457364 0
# 6 f19
-0.9065939866848107 -0.2962957610652136 0
# 7 f20
-0.1954805620516266 -0.07111892482963184 0
# 8 f21
-0.1407581310832468 0.7233857048236082 0
# 9 f22
-0.1676297826663962 0.2080621273999375 0
# 10 f23
0.05868313821742954 0.06632066014880154 0
# 11 f24
0.08806341399736994 0.1054080604689985 0
# 12 f25
0.4761588899009253 -0.03168366595227294 0
# 13 f26
3.094213357897477 -0.064721945677682 0
# 14 f27
0.5410515627308725 0.211561543495592 0
4 7 1 2 6 # p0(v2)
3 8 3 6 # p1(v0)
3 14 5 11 # p2(v8)
4 9 4 3 8 # p3(v7)
5 14 5 4 3 13 # p4(v1)
4 9 7 6 8 # p5(v9)
5 14 11 10 12 13 # p6(v10)
7 11 5 4 9 7 1 10 # p7(v5)
3 13 2 12 # p8(v6)
4 12 2 1 10 # p9(v3)
}
}
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Tcv Fv
23
4 0 1 0 6
4 0 7 1 7
4 0 9 1 2
4 0 8 0 2
4 0 5 6 7
4 1 4 0 3
4 1 3 3 8
4 1 5 6 8
4 2 7 5 11
4 2 4 5 14
4 2 6 11 14
4 3 4 3 4
4 3 7 4 9
4 3 5 8 9
4 4 8 0 13
4 4 7 4 5
4 4 6 13 14
4 5 7 7 9
4 6 7 10 11
4 6 9 10 12
4 6 8 12 13
4 7 9 1 10
4 8 9 2 12
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Tcv Fi
19
5 0 7 0.02051532578114336 0.9997895385570373 0.07511430445246037
5 0 9 0.619259133056969 0.7851866823409139 0.1370614663104577
5 0 5 -0.301880639203215 0.9533457293522945 0.008789126238507583
5 1 3 0.9648718030091262 -0.2627211520946079 0.3258622775065156
5 1 5 0.7995952824356682 -0.6005392446015695 0.5469710423089692
5 2 7 -0.9458410914974847 0.3246299888101017 0.04907537812572171
5 2 4 0.444671031232542 0.8956939622340812 -0.4300843534994401
5 2 6 0.2281595097543261 -0.9736237661995858 0.08253528745668784
5 3 4 0.9992944873266901 0.03755699133966539 -0.1938837324602516
5 3 7 0.6877523324625972 -0.7259454037269313 0.2663295190946441
5 3 5 -0.9986432053419565 0.05207445078292259 -0.1782370644858237
5 4 7 -0.9970183790688239 -0.07716444646969993 0.2145489484590235
5 4 6 -0.1075842248297359 -0.9941959739245502 0.2685422477498993
5 5 7 0.9950609206245129 -0.09926612839179765 0.187455367716064
5 6 7 -0.7993641842155074 0.6008468199079334 0.007060641163779212
5 6 9 -0.2285415587894343 -0.973534157544611 0.07797696388863314
5 6 8 -0.01261839651625044 -0.9999203848653946 -0.02567278177543585
5 7 9 0.5936952885926361 -0.8046899429612046 0.01852766555277016
5 8 9 -0.4674785097727932 0.8840044360186256 0.2506025495170936
Voronoi ridge statistics
19 bounded ridges
4.2e-017 ave. distance of midpoint to ridge
1.7e-016 max. distance of midpoint to ridge
19 bounded ridges with ok normal
1.2e-017 ave. angle to ridge
1.1e-016 max. angle to ridge
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Tcv Fo
4
5 0 1 -0.3854955578888161 0.9227096915324941 -0.07609298438083822
5 0 8 0.719062520784207 0.6949453872092842 0.1071733734620186
5 1 4 0.9929212365203526 -0.1187746524595787 0.07521211888503937
5 4 8 -0.06640144810487483 -0.9977929883946747 0.1408811441173877
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D2 | qhull v Qu o Fv Fi Fo Tcv
2
3 10 1
-10.101 -10.101
-0.06934933486244874 0.05349366577784781
-0.3051278694340224 0.161498505581022
3 0 2 1
2 0 1
0
0
3 0 1 2
0
0
0
2 0 2
0
5
4 0 8 0 2
4 0 4 1 2
4 0 1 0 1
4 1 4 0 1
4 4 8 0 2
1
5 0 4 0.4164624817835529 0.9091529031283372 -0.01975252543405325
4
5 0 8 0.7190625207842071 0.6949453872092841 0.1071733734620185
5 0 1 -0.3854955578888162 0.9227096915324941 -0.07609298438083828
5 1 4 0.9929212365203528 -0.1187746524595786 0.07521211888503934
5 4 8 -0.06640144810487485 -0.9977929883946747 0.1408811441173877
Voronoi ridge statistics
1 bounded ridges
1.2e-016 ave. distance of midpoint to ridge
1.2e-016 max. distance of midpoint to ridge
1 bounded ridges with ok normal
0 max. angle to ridge
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 20 distance computations.
rbox 10 D3 | qhull v Fv Tcv
32
6 0 1 0 17 15 3
7 0 9 0 7 12 11 2
6 0 6 0 7 18 17
5 0 7 0 2 3
6 0 2 2 3 15 11
5 0 8 7 18 12
7 0 5 11 12 18 17 15
5 1 7 0 5 3
6 1 2 3 5 0 15
5 1 5 15 0 17
6 2 3 1 4 13 9
6 2 9 1 2 11 9
7 2 7 1 2 3 5 4
6 2 4 4 5 0 13
7 2 5 9 11 15 0 13
7 3 9 0 6 10 9 1
5 3 7 0 4 1
5 3 6 0 8 6
7 3 4 0 8 14 13 4
6 3 8 6 8 14 10
6 3 5 9 10 14 13
5 4 7 0 5 4
5 4 6 0 16 8
5 4 8 8 16 14
6 4 5 13 0 16 14
6 5 9 9 11 12 10
7 5 8 10 12 18 16 14
6 5 6 0 17 18 16
5 6 9 0 6 7
7 6 8 6 7 18 16 8
5 7 9 0 1 2
6 8 9 6 7 12 10
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 180 distance computations.
rbox 10 D3 | qhull v Fi Tcv
13
6 0 2 0.1026012494065407 0.8309156055795224 -0.5468566905731633 0.2399036185798247
6 0 8 -0.1644981128676531 0.5492243080463513 -0.8193247404503221 0.122023739903044
6 0 5 -0.1640386761614814 0.6276090456203117 -0.7610507201092119 0.1709974344854013
6 2 3 0.8628264983391891 0.1277424492346306 -0.4890933453107607 -0.1660057988150949
6 2 9 0.514615149546644 -0.7556910962035636 -0.4050953159143434 -0.3000434746332833
6 2 7 0.9862472983740704 0.008356748990702902 0.1650649302430821 -0.2195655184060844
6 3 8 -0.9471370887617876 -0.1545163381156413 -0.281169052968456 0.0437290219976465
6 3 5 -0.9850113492204077 -0.1553182373520525 -0.07502590921037534 0.09265233510028302
6 4 8 -0.7177135399298968 -0.2457215366779669 -0.6515429387338296 -0.02974683605231299
6 5 9 0.7110332662678565 -0.6935177833709648 -0.1160378317993181 -0.270606286195582
6 5 8 -0.1310037283001487 -0.04490613421135449 -0.9903643078593113 -0.2004293237314498
6 6 8 0.5636530776159621 0.07101685912338829 0.8229531054770393 0.4221671959133706
6 8 9 0.7278413449934531 -0.6852671087526033 0.02561183671604039 -0.2412830130907243
Voronoi ridge statistics
15 non-simplicial Voronoi vertices for all ridges
4.5e-017 ave. distance to ridge
1.1e-016 max. distance to ridge
13 bounded ridges
5.1e-017 ave. distance of midpoint to ridge
1.1e-016 max. distance of midpoint to ridge
13 bounded ridges with ok normal
6e-017 ave. angle to ridge
2.2e-016 max. angle to ridge
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 180 distance computations.
rbox 10 D3 | qhull v Fo Tcv
19
6 0 1 -0.1769702595802887 0.8331351847724079 0.523991689932513 0.004105600879712693
6 0 9 0.5856843296472445 -0.1558732679166011 -0.7954102025713887 -0.1264594278193165
6 0 6 -0.305501768024369 0.3812318858994052 -0.8725427891556765 -0.04822326899809229
6 0 7 0.6633910639781613 0.6672883530766242 -0.3385831509130508 0.06175731395259272
6 1 7 0.7533877382120365 0.334939238848763 -0.5658821628140998 0.06152842458597928
6 1 2 0.2077539373736715 0.4344067294949107 -0.8764297432625574 0.2556318087147513
6 1 5 -0.08886729274769867 0.2768317827550707 -0.9568002760954578 0.1656561460661368
6 2 4 0.8896724708236493 0.4529391082738924 -0.05769799697211265 -0.124969949041603
6 2 5 -0.6080629223625024 -0.1069684332549472 -0.7866493734408968 -0.05602222006342443
6 3 9 0.1157648604151236 -0.9728190902550374 -0.2005530222370839 -0.2615067759720444
6 3 7 0.3131056731324619 -0.1651787990807294 0.9352437125084113 -0.1060546443225209
6 3 6 -0.8429664438017094 -0.1288333013498811 -0.5223117412882753 -0.1470675860428305
6 3 4 -0.6546392846048743 0.1665291828386517 0.7373706247980789 0.1638426312062793
6 4 7 0.8997625993863546 -0.3161631359012113 0.3007792151107228 -0.2534488584590283
6 4 6 -0.6610636619910347 -0.1756381951302929 -0.7294834194184101 -0.1931488689248214
6 4 5 -0.8177140658972856 -0.2799433900977096 -0.5029666040348318 0.01966883326066575
6 5 6 -0.4656867325018191 -0.06587339986788444 -0.8824945112359766 -0.374728122564582
6 6 9 0.7885740013077054 -0.5314391513195501 0.309392102204163 -0.04784058563315544
6 7 9 -0.0125726543874506 -0.8388634914110149 -0.5441966291143082 -0.2018836580171401
Voronoi ridge statistics
14 non-simplicial Voronoi vertices for all ridges
5.4e-017 ave. distance to ridge
1.2e-016 max. distance to ridge
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 180 distance computations.
rbox 10 D3 | qhull v Qu o Fv Fi Fo Tcv
3
10 10 1
-10.101 -10.101 -10.101
-0.04510412048603351 -0.1962229636993575 -0.06746145990413344
-0.2032838761823815 -0.3188041900902701 0.1251484339163768
0.1359785067833994 0.06954805978697726 -0.07249043373758879
-0.9550934192592715 0.3815223390696589 -0.9370156532984113
-0.01637948561987637 -0.8836250780525146 -0.03718065630611937
0.09499885792019704 -0.7038538868165176 -0.181396220925921
2.128743389186444 -4.06034590041635 -1.216246894786401
2.789531685277142 -5.39366622961672 -1.494034092231972
2.640156785602008 -4.796303906482421 -1.459799746992416
3 0 3 4
7 0 1 3 4 6 7 9
4 0 7 8 9
3 0 2 5
5 0 5 6 7 8
3 0 8 9
9 0 1 2 3 5 6 7 8 9
6 0 1 2 4 5 6
0
5 0 1 2 3 4
18
5 0 1 0 3 4
5 0 9 0 3 4
8 1 6 0 3 1 6 7 9
5 1 2 0 7 9
5 1 4 0 6 7
6 1 7 0 4 1 6
5 1 9 1 3 4
5 2 5 0 9 8
5 2 4 0 7 8
5 2 6 7 9 8
5 3 6 0 5 2
5 3 7 0 2 5
7 4 6 0 5 6 7 8
5 4 7 0 6 5
5 5 6 0 9 8
6 6 9 0 3 1 2
6 6 7 1 2 5 6
6 7 9 0 2 1 4
3
6 1 9 0.5123553720802024 -0.363812082853534 -0.7779027838170592 -0.100757404152973
6 2 6 -0.5221667006142706 -0.08192192666458514 -0.8488997200501182 -0.2535440955968324
6 6 7 0.752213645322669 0.06033708575303686 0.6561509489997043 0.09003235761431797
15
6 0 1 -0.1769702595802886 0.8331351847724078 0.5239916899325134 0.004105600879712498
6 0 9 0.5856843296472447 -0.1558732679166012 -0.7954102025713884 -0.1264594278193166
6 1 6 -0.2436653478720987 0.147883680687048 -0.9585184480399009 -0.04663519095132841
6 1 2 0.207753937373674 0.4344067294949119 -0.8764297432625561 0.2556318087147511
6 1 4 0.444220078847362 0.4986447037065236 -0.744326528490203 0.1737545932855555
6 1 7 0.7533877382120362 0.3349392388487629 -0.5658821628141001 0.06152842458597942
6 2 5 -0.6080629223625025 -0.1069684332549475 -0.7866493734408965 -0.05602222006342417
6 2 4 0.8896724708236504 0.4529391082738911 -0.05769799697210674 -0.1249699490416038
6 3 6 -0.8429664438017096 -0.1288333013498811 -0.5223117412882751 -0.1470675860428304
6 3 7 0.3131056731324614 -0.1651787990807291 0.9352437125084115 -0.1060546443225207
6 4 6 -0.661063661991035 -0.1756381951302929 -0.7294834194184101 -0.1931488689248215
6 4 7 0.8997625993863546 -0.3161631359012115 0.3007792151107228 -0.2534488584590282
6 5 6 -0.4656867325018209 -0.06587339986788572 -0.8824945112359753 -0.3747281225645818
6 6 9 0.7885740013077054 -0.5314391513195503 0.3093921022041629 -0.04784058563315553
6 7 9 -0.01257265438745033 -0.8388634914110151 -0.5441966291143079 -0.2018836580171402
Voronoi ridge statistics
9 non-simplicial Voronoi vertices for all ridges
7.9e-017 ave. distance to ridge
2.2e-016 max. distance to ridge
3 bounded ridges
1.1e-016 ave. distance of midpoint to ridge
1.4e-016 max. distance of midpoint to ridge
3 bounded ridges with ok normal
7.4e-017 ave. angle to ridge
2.2e-016 max. angle to ridge
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 90 distance computations.
rbox 5 D2 | qhull v f FnN o
Vertices and facets:
- p3(v5): 0.43 -0.11 0.19
neighbors: f5 f6 f7 f8
- p2(v1): 0.47 -0.11 0.24
neighbors: f1 f5 f7
- p4(v0): -0.39 0.45 0.36
neighbors: f1 f3 f5 f6
- p0(v3): -0.34 0.23 0.17
neighbors: f3 f6 f8
- p1(v2): 0.32 -0.23 0.16
neighbors: f1 f3 f7 f8
- f5
- flags: top simplicial
- normal: 0.437 0.773 -0.4599
- offset: -0.01170704
- center: 0.4751017705052502 0.8404705693422864
- vertices: p3(v5) p2(v1) p4(v0)
- neighboring facets: f1 f6 f7
- f6
- flags: bottom simplicial
- normal: 0.3235 0.6691 -0.669
- offset: 0.0657
- center: 0.24177356134713 0.5000766029034823
- vertices: p3(v5) p0(v3) p4(v0)
- neighboring facets: f3 f5 f8
- f7
- flags: top simplicial
- normal: 0.6288 -0.3317 -0.7033
- offset: -0.1682885
- center: 0.447029359505762 -0.2357835939937328
- vertices: p3(v5) p1(v2) p2(v1)
- neighboring facets: f1 f5 f8
- f8
- flags: top simplicial
- normal: 0.1177 0.1841 -0.9758
- offset: 0.15929
- center: 0.06029550723695781 0.09433023738340306
- vertices: p3(v5) p0(v3) p1(v2)
- neighboring facets: f3 f7 f6
4
3 -1 1 2
3 -3 0 3
3 -1 0 3
3 -3 2 1
5
3 3 -3 1
4 3 -3 -1 2
3 2 -1 0
4 3 1 0 2
4 1 -3 -1 0
2
5 5 1
-10.101 -10.101
0.4751017705052502 0.8404705693422864
0.24177356134713 0.5000766029034823
0.447029359505762 -0.2357835939937328
0.06029550723695781 0.09433023738340306
3 2 4 0
3 3 4 0
3 1 3 0
4 3 4 2 1
3 1 2 0
echo === check Halfspace ${d:-`date`}
date
-=== check Halfspace Tue Jan 24 20:16:51 EST 2012
+=== check Halfspace Sun Aug 30 22:24:35 EDT 2015
rbox 100 s D4 | qhull FA FV n s Tcv | qhull H Fp Tcv | qhull FA Tcv
Convex hull of 100 points in 4-d:
Number of vertices: 100
Number of facets: 584
Statistics for: rbox 100 s D4 | qhull FA FV n s Tcv
Number of points processed: 100
Number of hyperplanes created: 1718
Number of distance tests for qhull: 4091
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Total facet area: 1.7919449
Total volume: 0.18640279
Output completed. Verifying that all points are below 2.8e-015 of
all facets. Will make 58400 distance computations.
Output completed. Verifying that all points are below outer planes of
all facets. Will make 58400 distance computations.
Convex hull of 100 points in 4-d:
Number of vertices: 100
Number of facets: 584
Statistics for: | qhull FA Tcv
Number of points processed: 100
Number of hyperplanes created: 1718
Number of distance tests for qhull: 4091
- CPU seconds to compute hull (after input): 0.016
+ CPU seconds to compute hull (after input): 0
Total facet area: 1.7919449
Total volume: 0.18640279
Output completed. Verifying that all points are below 2.8e-015 of
all facets. Will make 58400 distance computations.
rbox d D3 | qhull FQ n s FD Tcv | qhull Fd H0.1,0.1 Fp FQ Tcv
Convex hull of 6 points in 3-d:
Number of vertices: 6
Number of facets: 8
Statistics for: rbox d D3 | qhull FQ n s FD Tcv
Number of points processed: 6
Number of hyperplanes created: 11
Number of distance tests for qhull: 11
Number of distance tests for merging: 59
Number of distance tests for checking: 54
Number of merged facets: 1
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
3
6
-1.387778780781446e-017 -1.387778780781446e-017 0.5
-2.775557561562891e-017 0.5 0
-0.5 0 0
0.5 -2.775557561562891e-017 0
0 -0.5 0
-1.387778780781446e-017 1.387778780781446e-017 -0.4999999999999999
rbox d D3 | qhull FQ n s FD Tcv | qhull Fd H0.1,0.1 Fp FQ Tcv
Output completed. Verifying that all points are below outer planes of
all facets. Will make 48 distance computations.
rbox 5 r D2 | qhull s n Tcv | qhull H0 Fp Tcv
Convex hull of 5 points in 2-d:
Number of vertices: 5
Number of facets: 5
Statistics for: rbox 5 r D2 | qhull s n Tcv
Number of points processed: 5
Number of hyperplanes created: 8
Number of distance tests for qhull: 8
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 25 distance computations.
2
5
-0.4045084971874738 -0.2938926261462365
0.5 -1.528090898784888e-016
0.1545084971874736 -0.4755282581475768
-0.4045084971874737 0.2938926261462366
0.1545084971874737 0.4755282581475768
Output completed. Verifying that all points are below 6.4e-015 of
all facets. Will make 25 distance computations.
echo === check qhull ${d:-`date`}
date
-=== check qhull Tue Jan 24 20:16:51 EST 2012
+=== check qhull Sun Aug 30 22:24:35 EDT 2015
rbox 10 s D3 | qhull Tcv
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 s D3 | qhull Tcv
Number of points processed: 10
Number of hyperplanes created: 29
Number of distance tests for qhull: 49
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 160 distance computations.
rbox 10 s D3 | qhull f Pd0:0.5 Pd2 Tcv
Vertices and facets:
- p7(v8): 0.2 0.093 0.45
- p9(v5): 0.29 -0.16 0.38
- p3(v1): 0.48 -0.13 0.022
- p8(v10): 0.32 0.025 -0.38
- f16
- flags: bottom simplicial
- normal: 0.858 0.1759 0.4826
- offset: -0.4016457
- vertices: p7(v8) p9(v5) p3(v1)
- neighboring facets: f7 f27 f23
- f27
- flags: bottom simplicial
- normal: 0.646 0.7625 0.03668
- offset: -0.2138755
- vertices: p8(v10) p7(v8) p3(v1)
- neighboring facets: f16 f26 f28
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 20 distance computations.
rbox 10 s D3 | qhull f Tcv PD2:-0.5
Vertices and facets:
- p4(v7): 0.23 -0.32 -0.31
- p1(v3): -0.072 0.057 -0.49
- p6(v2): -0.13 -0.47 -0.09
- p0(v9): -0.37 -0.27 0.19
- p8(v10): 0.32 0.025 -0.38
- p5(v6): 0.028 0.16 -0.47
- f12
- flags: top simplicial
- normal: -0.2354 -0.5691 -0.7879
- offset: -0.3715833
- vertices: p4(v7) p1(v3) p6(v2)
- neighboring facets: f21 f11 f25
- f21
- flags: bottom simplicial
- normal: -0.8148 -0.2922 -0.5006
- offset: -0.2881945
- vertices: p0(v9) p1(v3) p6(v2)
- neighboring facets: f12 f19 f20
- f24
- flags: top simplicial
- normal: 0.2636 -0.06941 -0.9621
- offset: -0.4497787
- vertices: p8(v10) p5(v6) p1(v3)
- neighboring facets: f9 f25 f28
- f25
- flags: bottom simplicial
- normal: 0.2402 -0.2624 -0.9346
- offset: -0.4268812
- vertices: p8(v10) p4(v7) p1(v3)
- neighboring facets: f12 f24 f26
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 40 distance computations.
rbox 10 s D3 | qhull QR-1
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
-Statistics for: rbox 10 s D3 | qhull QR-1 QR-1327454211
+Statistics for: rbox 10 s D3 | qhull QR-1 QR-1440987875
Number of points processed: 10
Number of hyperplanes created: 29
Number of distance tests for qhull: 49
CPU seconds to compute hull (after input): 0
rbox 10 s D3 | qhull QR-40
Convex hull of 10 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 10 s D3 | qhull QR-40 QR-40
Number of points processed: 10
Number of hyperplanes created: 29
Number of distance tests for qhull: 49
CPU seconds to compute hull (after input): 0
rbox 1000 D3 | qhull Tcvs
qhull invoked by: rbox 1000 D3 | qhull Tcvs
-2012.1 2012/01/22 with options:
- run-id 315332402 Tcheck-frequently Tverify Tstatistics _pre-merge
+2015.0.2.r 2015/08/30 with options:
+ run-id 1510127906 Tcheck-frequently Tverify Tstatistics _pre-merge
_zero-centrum _max-width 1 Error-roundoff 6.9e-016 _one-merge 4.9e-015
_near-inside 2.4e-014 Visible-distance 1.4e-015
U-coplanar-distance 1.4e-015 Width-outside 2.8e-015 _wide-facet 8.3e-015
precision constants:
0.5 max. abs. coordinate in the (transformed) input('Qbd:n')
6.9e-016 max. roundoff error for distance computation('En')
6.7e-016 max. roundoff error for angle computations
2.8e-015 min. distance for outside points ('Wn')
1.4e-015 min. distance for visible facets ('Vn')
1.4e-015 max. distance for coplanar facets ('Un')
8.3e-015 max. facet width for recomputing centrum and area
2.4e-014 max. distance for near-inside points
1.4e-015 radius of pre-merge centrum
4.9e-015 max. distance for merging two simplicial facets
2.2e-016 max. roundoff error for arithmetic operations
1.1e-308 min. denominator for divisions
zero diagonal for Gauss: 8.88e-015 1.78e-014 2.66e-014
precision statistics
3.7e-017 ave. distance of a new vertex to a facet(!0s)
1.4e-016 max. distance of a new vertex to a facet
1.1e-016 max. distance of an output vertex to a facet
-1.4e-016 min. distance of an output vertex to a facet
0.0026 min. denominator in hyperplane computation
summary information
73 number of vertices in output
142 number of facets in output
3 average number of neighbors per facet
3 maximum number of neighbors
3 average number of vertices per facet
3 maximum number of vertices
82 vertices created altogether
368 facets created altogether
0 maximum merges for a facet(at most 511)
0.93 average angle(cosine) of facet normals for all ridges
1 maximum angle(cosine) of facet normals across a ridge
0.21 minimum angle(cosine) of facet normals across a ridge
build hull statistics
81 points processed
73 max. vertices at any one time
2.78 ave. visible facets per iteration
0.21 ave. visible facets without an horizon neighbor
2.78 ave. facets deleted per iteration
8 maximum
5.43 ave. visible vertices per iteration
11 maximum
4.38 ave. horizon facets per iteration
4.48 ave. new or merged facets per iteration
10 maximum(includes initial simplex)
-0.77 average new facet balance
1.5 standard deviation
77 number of trials
7 determinants computed(area & initial hull)
504 distance tests for facet visibility
73 points checked for facets' outer planes
12.4 ave. distance tests per check
1629 max visit_id/2
619 max vertex_visit/2
partitioning statistics(see previous for outer planes)
8 total vertices deleted
1 maximum vertices deleted per iteration
135 calls to findbest
2.59 ave. facets tested
7 max. facets tested
2045 calls to findbestnew
4.47 ave. facets tested
13 max. facets tested
36 calls due to qh_sharpnewfacets
927 calls to findhorizon
3.02 ave. facets tested
6 max. facets tested
5 horizon facets better than bestfacet
919 inside points
8 inside points that were coplanar with a facet
-3.1e-017 difference in max_outside at final check
3747 distance tests for initial partition
3132 partitions of a point
8558 distance tests for partitioning
513 distance tests for checking flipped facets
1162 distance tests for statistics
16990 total number of distance tests
8 partitions of coplanar points or deleted vertices
75 distance tests for these partitions
statistics for matching ridges
726 total lookups for matching ridges of new facets
- 0.563 average number of tests to match a ridge
+ 0.574 average number of tests to match a ridge
statistics for determining merges
1089 distance tests for checking simplicial convexity
statistics for merging
1.4e-016 max distance of vertex or coplanar point above facet(w/roundoff)
-6.9e-016 max distance of merged vertex below facet(or roundoff)
memory usage statistics(in bytes)
- 21584 for facets a
+ 21584 for fac
Convex hull of 1000 points in 3-d:
Number of vertices: 73
Number of facets: 142
Statistics for: rbox 1000 D3 | qhull Tcvs
Number of points processed: 81
Number of hyperplanes created: 368
Number of distance tests for qhull: 12884
CPU seconds to compute hull (after input): 0
-nd their normals, neighbor and vertex sets
- 1752 for vertices and their neighbor sets
- 30368 for input points and outside and coplanar sets
+ets and their normals, neighbor and vertex sets
+ 2044 for vertices and their neighbor sets
+ 30600 for input points, outside and coplanar sets, and qhT
memory statistics:
1166 quick allocations
673 short allocations
69 long allocations
1184 short frees
68 long frees
- 25312 bytes of short memory in use
+ 25680 bytes of short memory in use
680 bytes of short memory in freelists
- 105072 bytes of dropped short memory
- 3100 bytes of unused short memory (estimated)
+ 104704 bytes of dropped short memory
+ 2948 bytes of unused short memory (estimated)
10916 bytes of long memory allocated (max, except for input)
96 bytes of long memory in use (in 1 pieces)
131064 bytes of short memory buffers (minus links)
65536 bytes per short memory buffer (initially 131072 bytes)
73 calls to qh_setlarger
15 average copy size
- freelists(bytes->count): 16->1 24->13 88->4
+ freelists(bytes->count): 16->1 24->13 32->0 88->4
- size in bytes: merge 24 ridge 16 vertex 24 facet 88
+ size in bytes: merge 24 ridge 20 vertex 28 facet 88
normal 24 ridge vertices 16 facet vertices or neighbors 20
Output completed. Verifying that all points are below outer planes of
all facets. Will make 142000 distance computations.
rbox 100 D3 | qhull T8 Tz TO q_test.log.1
tail -n -10 q_test.log.1
-qh_mem 00450170 n 1022 free short: 88 bytes (tot 8984 cnt 228)
-qh_mem 004501C8 n 1023 free short: 88 bytes (tot 8896 cnt 227)
-qh_mem 00450220 n 1024 free short: 88 bytes (tot 8808 cnt 226)
-qh_mem 00450278 n 1025 free short: 88 bytes (tot 8720 cnt 225)
-qh_mem 00362CC8 n 30 free long: 96 bytes (tot 0 cnt 0)
-qh_mem 004502D0 n 1026 free short: 16 bytes (tot 8704 cnt 224)
-qh_mem 00450050 n 1027 free short: 88 bytes (tot 8616 cnt 223)
-qh_mem 004500A8 n 1028 free short: 88 bytes (tot 8528 cnt 222)
-qh_mem 00450100 n 1029 free short: 88 bytes (tot 8440 cnt 221)
+qh_mem 00270170 n 1022 free short: 32 bytes (tot 9032 cnt 228)
+qh_mem 00270190 n 1023 free short: 32 bytes (tot 9000 cnt 227)
+qh_mem 002701B0 n 1024 free short: 32 bytes (tot 8968 cnt 226)
+qh_mem 002701D0 n 1025 free short: 32 bytes (tot 8936 cnt 225)
+qh_mem 00263408 n 30 free long: 96 bytes (tot 0 cnt 0)
+qh_mem 002701F0 n 1026 free short: 16 bytes (tot 8920 cnt 224)
+qh_mem 00270050 n 1027 free short: 88 bytes (tot 8832 cnt 223)
+qh_mem 002700A8 n 1028 free short: 88 bytes (tot 8744 cnt 222)
+qh_mem 00270100 n 1029 free short: 88 bytes (tot 8656 cnt 221)
qh_freebuffers: finished
rm q_test.log.1
rbox 100 s D3 | qhull TcvV-2
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 78
Number of facets: 152
Statistics for: rbox 100 s D3 | qhull TcvV-2
Number of points processed: 78
Number of hyperplanes created: 390
Number of distance tests for qhull: 1489
CPU seconds to compute hull (after input): 0
rbox 100 s D3 | qhull TcvC2
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 79
Number of facets: 154
Statistics for: rbox 100 s D3 | qhull TcvC2
Number of points processed: 79
Number of hyperplanes created: 395
Number of distance tests for qhull: 1496
CPU seconds to compute hull (after input): 0
rbox 100 s D3 | qhull TcvV2
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 79
Number of facets: 154
Statistics for: rbox 100 s D3 | qhull TcvV2
Number of points processed: 79
Number of hyperplanes created: 395
Number of distance tests for qhull: 1496
CPU seconds to compute hull (after input): 0
rbox 100 s D3 | qhull T1cvV2P2
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 79
Number of facets: 154
Statistics for: rbox 100 s D3 | qhull T1cvV2P2
Number of points processed: 79
Number of hyperplanes created: 395
Number of distance tests for qhull: 1496
CPU seconds to compute hull (after input): 0
qh_readpoints: read in 100 3-dimensional points
qh_initqhull_globals: for rbox 100 s D3 | qhull T1cvV2P2
Trace level 1 for rbox 100 s D3 | qhull T1cvV2P2
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315332402 Tcheck-frequently Tverify TV-stop-after-point 2
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 Tcheck-frequently Tverify TV-stop-after-point 2
Trace-point 2 _pre-merge _zero-centrum _max-width 0.94
Error-roundoff 6.7e-016 _one-merge 4.7e-015 _near-inside 2.3e-014
Visible-distance 1.3e-015 U-coplanar-distance 1.3e-015
Width-outside 2.7e-015 _wide-facet 8.1e-015
qh_findbest: point p2 starting at f7 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p41. Last merge was #0. max_outside 5.6e-017
qh_findbest: point p2 starting at f15 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p52. Last merge was #0. max_outside 1.1e-016
qh_findbest: point p2 starting at f37 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p73. Last merge was #0. max_outside 1.1e-016
qh_findbest: point p2 starting at f52 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p87. Last merge was #0. max_outside 1.1e-016
qh_findbest: point p2 starting at f72 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p76. Last merge was #0. max_outside 1.1e-016
qh_findbest: point p2 starting at f120 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p84. Last merge was #0. max_outside 1.7e-016
qh_findbest: point p2 starting at f211 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p10. Last merge was #0. max_outside 1.7e-016
qh_findbest: point p2 starting at f289 isnewfacets? 1, unless 0 exit if > 2.7e-015
testhorizon? 1 noupper? 0 Last point added was p6. Last merge was #0. max_outside 1.7e-016
qh_addpoint: add p2(v79) to hull of 152 facets(0.014 above f288) and 22 outside at 0 CPU secs. Previous was p56.
qh_findhorizon: find horizon for point p2 facet f288
qh_findhorizon: 5 horizon facets(good 5), 3 visible(good 3), 0 coplanar
qh_makenewfacets: created 5 new facets from point p2 to horizon
qh_matchnewfacets: match neighbors for new facets.
qh_partitionvisible: partitioned 0 points from outsidesets and 0 points from coplanarsets
qh_deletevisible: delete 3 visible facets and 0 vertices
qh_checkpolygon: check all facets from f390
qh_buildhull: completed the hull construction
Qhull: algorithm completed
qh_checkpolygon: check all facets from f62
qh_checkconvex: check all ridges are convex
-qh_freeqhull2: free global memory
+qh_freeqhull: free global memory
qh_freebuild: free memory from qh_inithull and qh_buildhull
rbox 100 s D3 | qhull TcvF100
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 s D3 | qhull TcvF100
Number of points processed: 100
Number of hyperplanes created: 514
Number of distance tests for qhull: 1691
CPU seconds to compute hull (after input): 0
-At 20:16:52 & 0 CPU secs, qhull has created 102 facets and merged 0.
+At 22:24:36 & 0 CPU secs, qhull has created 102 facets and merged 0.
The current hull contains 46 facets and 25 vertices. There are 75
outside points. Next is point p55(v26), 0.035 above f44.
-At 20:16:52 & 0 CPU secs, qhull has created 203 facets and merged 0.
+At 22:24:36 & 0 CPU secs, qhull has created 203 facets and merged 0.
The current hull contains 86 facets and 45 vertices. There are 55
outside points. Next is point p82(v46), 0.067 above f117.
-At 20:16:52 & 0 CPU secs, qhull has created 306 facets and merged 0.
+At 22:24:36 & 0 CPU secs, qhull has created 306 facets and merged 0.
The current hull contains 122 facets and 63 vertices. There are 37
outside points. Next is point p50(v64), 0.042 above f218.
-At 20:16:52 & 0 CPU secs, qhull has created 412 facets and merged 0.
+At 22:24:36 & 0 CPU secs, qhull has created 412 facets and merged 0.
The current hull contains 160 facets and 82 vertices. There are 18
outside points. Next is point p60(v83), 0.031 above f307.
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 19600 distance computations.
rbox 100 s D3 | qhull Qf Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 s D3 | qhull Qf Tcv
Number of points processed: 100
Number of hyperplanes created: 504
Number of distance tests for qhull: 4423
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 19600 distance computations.
rbox 100 D3 | qhull Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 26
Number of facets: 48
Statistics for: rbox 100 D3 | qhull Tcv
Number of points processed: 28
Number of hyperplanes created: 110
Number of distance tests for qhull: 1164
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 4800 distance computations.
rbox 100 D3 | qhull Qs Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 26
Number of facets: 48
Statistics for: rbox 100 D3 | qhull Qs Tcv
Number of points processed: 29
Number of hyperplanes created: 105
Number of distance tests for qhull: 1176
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 4800 distance computations.
rbox 100 D5 | qhull Qs Tcv
Convex hull of 100 points in 5-d:
Number of vertices: 78
Number of facets: 1174
Statistics for: rbox 100 D5 | qhull Qs Tcv
Number of points processed: 85
Number of hyperplanes created: 4015
Number of distance tests for qhull: 8584
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 117400 distance computations.
rbox 100 D3 | qhull Qr Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 26
Number of facets: 48
Statistics for: rbox 100 D3 | qhull Qr Tcv
Number of points processed: 56
Number of hyperplanes created: 294
Number of distance tests for qhull: 2129
Output completed. Verifying that all points are below outer planes of
all facets. Will make 4800 distance computations.
rbox 100 D3 | qhull Qxv Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 26
Number of facets: 48
Statistics for: rbox 100 D3 | qhull Qxv Tcv
Number of points processed: 28
Number of hyperplanes created: 110
Number of distance tests for qhull: 1164
CPU seconds to compute hull (after input): 0
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 4800 distance computations.
rbox 100 D3 | qhull Qi f Pd0 Pd1 Pd2 Tcv
Vertices and facets:
- p11(v14): -0.31 0.47 0.07
- p59(v8): 0.44 0.42 -0.11
- p33(v2): -0.067 0.49 -0.11
- p48(v25): 0.25 0.24 0.44
- p37(v15): 0.45 0.26 0.04
- p38(v5): 0.42 -0.25 0.42
- f42
- flags: bottom simplicial
- normal: 0.1292 0.9495 0.2858
- offset: -0.4221543
- coplanar set(furthest p70):
p70: 0.04762 0.3507 -0.06712
furthest distance= -0.1
- vertices: p11(v14) p59(v8) p33(v2)
- neighboring facets: f52 f41 f93
- f93
- flags: top simplicial
- normal: 0.142 0.9273 0.3463
- offset: -0.4120445
- coplanar set(furthest p28):
p27: 0.1182 0.3419 0.068
p25: 0.1663 0.2352 0.3516
p15: 0.2743 0.2665 0.07375
p44: -0.1321 0.3861 0.167
p28: -0.1003 0.4263 0.07335
furthest distance= -0.0056
- vertices: p48(v25) p11(v14) p59(v8)
- neighboring facets: f42 f94 f95
- f94
- flags: bottom simplicial
- normal: 0.7783 0.4631 0.4241
- offset: -0.4905394
- vertices: p48(v25) p37(v15) p59(v8)
- neighboring facets: f47 f93 f97
- f97
- flags: top simplicial
- normal: 0.8488 0.2736 0.4523
- offset: -0.4744876
- vertices: p48(v25) p37(v15) p38(v5)
- neighboring facets: f46 f99 f94
Output completed. Verifying that all points are below outer planes of
all facets. Will make 400 distance computations.
rbox c d | qhull Qc f Tcv
Vertices and facets:
- p6(v6): 0.5 0.5 -0.5
neighbors: f1 f9 f10
- p2(v2): -0.5 0.5 -0.5
neighbors: f1 f3 f10
- p4(v1): 0.5 -0.5 -0.5
neighbors: f1 f2 f9
- p0(v0): -0.5 -0.5 -0.5
neighbors: f1 f2 f3
- p5(v7): 0.5 -0.5 0.5
neighbors: f2 f9 f13
- p1(v3): -0.5 -0.5 0.5
neighbors: f2 f3 f13
- p7(v5): 0.5 0.5 0.5
neighbors: f9 f10 f13
- p3(v8): -0.5 0.5 0.5
neighbors: f3 f10 f13
- f1
- flags: bottom tested seen coplanar
- merges: 1
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- coplanar set(furthest p8):
p8: 0 0 -0.5
furthest distance= 0
- vertices: p6(v6) p2(v2) p4(v1) p0(v0)
- neighboring facets: f2 f3 f9 f10
- ridges:
- r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
- r3 tested
vertices: p4(v1) p0(v0)
between f2 and f1
- r1 tested
vertices: p6(v6) p4(v1)
between f9 and f1
- r2 tested
vertices: p6(v6) p2(v2)
between f1 and f10
- f2
- flags: top tested seen coplanar
- merges: 1
- normal: 0 -1 0
- offset: -0.5
- center: 0 -0.5 0
- coplanar set(furthest p10):
p10: 0 -0.5 0
furthest distance= 0
- vertices: p5(v7) p1(v3) p4(v1) p0(v0)
- neighboring facets: f1 f3 f9 f13
- ridges:
- r3 tested
vertices: p4(v1) p0(v0)
between f2 and f1
- r8 tested
vertices: p1(v3) p0(v0)
between f3 and f2
- r7 tested
vertices: p5(v7) p1(v3)
between f13 and f2
- r6 tested
vertices: p5(v7) p4(v1)
between f2 and f9
- f9
- flags: bottom tested seen coplanar
- merges: 1
- normal: 1 -0 -0
- offset: -0.5
- center: 0.5 0 0
- coplanar set(furthest p13):
p13: 0.5 0 0
furthest distance= 0
- vertices: p5(v7) p6(v6) p7(v5) p4(v1)
- neighboring facets: f2 f1 f10 f13
- ridges:
- r1 tested
vertices: p6(v6) p4(v1)
between f9 and f1
- r6 tested
vertices: p5(v7) p4(v1)
between f2 and f9
- r10 tested
vertices: p5(v7) p7(v5)
between f9 and f13
- r11 tested
vertices: p6(v6) p7(v5)
between f10 and f9
- f3
- flags: bottom tested seen coplanar
- merges: 1
- normal: -1 -0 -0
- offset: -0.5
- center: -0.5 0 0
- coplanar set(furthest p12):
p12: -0.5 0 0
furthest distance= 0
- vertices: p3(v8) p1(v3) p2(v2) p0(v0)
- neighboring facets: f1 f2 f10 f13
- ridges:
- r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
- r13 tested
vertices: p3(v8) p2(v2)
between f10 and f3
- r14 tested
vertices: p3(v8) p1(v3)
between f3 and f13
- r8 tested
vertices: p1(v3) p0(v0)
between f3 and f2
- f10
- flags: top tested seen coplanar
- merges: 1
- normal: 0 1 -0
- offset: -0.5
- center: 0 0.5 0
- coplanar set(furthest p11):
p11: 0 0.5 0
furthest distance= 0
- vertices: p3(v8) p6(v6) p7(v5) p2(v2)
- neighboring facets: f3 f1 f9 f13
- ridges:
- r2 tested
vertices: p6(v6) p2(v2)
between f1 and f10
- r11 tested
vertices: p6(v6) p7(v5)
between f10 and f9
- r16 tested
vertices: p3(v8) p7(v5)
between f13 and f10
- r13 tested
vertices: p3(v8) p2(v2)
between f10 and f3
- f13
- flags: bottom tested seen coplanar
- merges: 1
- normal: -0 -0 1
- offset: -0.5
- center: 0 0 0.5
- coplanar set(furthest p9):
p9: 0 0 0.5
furthest distance= 0
- vertices: p3(v8) p5(v7) p7(v5) p1(v3)
- neighboring facets: f10 f2 f9 f3
- ridges:
- r7 tested
vertices: p5(v7) p1(v3)
between f13 and f2
- r14 tested
vertices: p3(v8) p1(v3)
between f3 and f13
- r16 tested
vertices: p3(v8) p7(v5)
between f13 and f10
- r10 tested
vertices: p5(v7) p7(v5)
between f9 and f13
Output completed. Verifying that all points are below outer planes of
all facets. Will make 84 distance computations.
rbox c d | qhull Qc p Tcv
3
14
-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.5
0 0 0.5
0 -0.5 0
0 0.5 0
-0.5 0 0
0.5 0 0
Output completed. Verifying that all points are below outer planes of
all facets. Will make 84 distance computations.
rbox 100 D3 | qhull QbB FO Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 26
Number of facets: 48
Statistics for: rbox 100 D3 | qhull QbB FO Tcv
Number of points processed: 28
Number of hyperplanes created: 110
Number of distance tests for qhull: 1164
CPU seconds to compute hull (after input): 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315332402 QbBound-unit-box 0.5 Tcheck-frequently Tverify
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 QbBound-unit-box 0.5 Tcheck-frequently Tverify
_pre-merge _zero-centrum _max-width 1 Error-roundoff 6.9e-016
_one-merge 4.9e-015 _near-inside 2.4e-014 Visible-distance 1.4e-015
U-coplanar-distance 1.4e-015 Width-outside 2.8e-015 _wide-facet 8.3e-015
Output completed. Verifying that all points are below outer planes of
all facets. Will make 4800 distance computations.
rbox 1000 D2 B1e6 | qhull d Qbb FO Tcv
Delaunay triangulation by the convex hull of 1000 points in 3-d:
Number of input sites: 1000
Number of Delaunay regions: 1982
Statistics for: rbox 1000 D2 B1e6 | qhull d Qbb FO Tcv
Number of points processed: 1000
Number of hyperplanes created: 5422
Number of facets in hull: 1996
Number of distance tests for qhull: 27767
CPU seconds to compute hull (after input): 0.015
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315332402 delaunay Qbbound-last Tcheck-frequently Tverify
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 delaunay Qbbound-last Tcheck-frequently Tverify
_pre-merge _zero-centrum Pgood _max-width 2e+006 Error-roundoff 2.8e-009
_one-merge 1.9e-008 _near-inside 9.7e-008 Visible-distance 5.5e-009
U-coplanar-distance 5.5e-009 Width-outside 1.1e-008 _wide-facet 3.3e-008
qhull output completed. Verifying that 1000 points are
below 8.3e-009 of the nearest facet.
rbox 10 D3 | qhull QbB p Tcv
3
9
-0.08928142660407056 -0.3194671263098747 0.3605569202297553
-0.1534778158747162 0.03516440701453921 0.5
-0.01663016790622804 0.3709299907861695 0.0764863283135003
0.3932651765570926 0.4421392241401818 -0.09396622763110282
0.199424728304684 0.5 0.06620718432588452
-0.2331094527352667 0.3262436269787957 -0.1289660986727641
-0.5 0.2819439085196089 -0.5
0.4999999999999999 0.3760666748352666 0.1399187075693636
0.4888102268053206 -0.5 -0.2153953634886358
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 140 distance computations.
rbox 10 D3 | qhull Qbb p Tcv
3
9
-0.0222149361131852 -0.366434993563625 0.5972263834933854
-0.06676722137887703 -0.1566931052661437 0.6939998615477234
0.02820502736438535 0.04189077954915421 0.4000814320337247
0.3126723396709863 0.08400649026409401 0.2817873818077145
0.1781470954214661 0.1182274414396169 0.3929477075294902
-0.1220315663349177 0.01546165115708642 0.2574974761506134
-0.3072535691850387 -0.01073880122111998 0
0.3867462923626847 0.04492879989084675 0.4441034944549365
0.3789805913148268 -0.4732086509216658 0.1975155783347269
QH7040 qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 140 distance computations.
rbox 10 D3 | qhull Qb0:-10B2:20 p Tcv
3
9
-5.733970380575339 -0.366434993563625 17.14322461142018
-6.400761988815289 -0.1566931052661437 20
-4.97936018866004 0.04189077954915421 11.32346018178494
-0.7218812392989191 0.08400649026409401 7.831392539952951
-2.735252796494545 0.1182274414396169 11.11287098934976
-7.227875597731384 0.01546165115708642 7.114348923589699
-10 -0.01073880122111998 -0.4870359524963758
0.3867462923626847 0.04492879989084675 12.62300161615219
0.2705209571204694 -0.4732086509216658 5.343669467959106
Output completed. Verifying that all points are below 7.5e-014 of
all facets. Will make 140 distance computations.
rbox 10 D3 | qhull Qb0:-10B2:20 p Tcv | qhull QbB p Tcv
Output completed. Verifying that all points are below 7.5e-014 of
all facets. Will make 140 distance computations.
3
9
-0.08928142660407051 -0.3194671263098747 0.3605569202297555
-0.1534778158747163 0.03516440701453921 0.5
-0.01663016790622796 0.3709299907861695 0.07648632831350066
0.3932651765570927 0.4421392241401818 -0.09396622763110274
0.1994247283046841 0.5 0.06620718432588446
-0.2331094527352668 0.3262436269787957 -0.128966098672764
-0.5 0.2819439085196089 -0.4999999999999999
0.5 0.3760666748352666 0.1399187075693635
0.4888102268053207 -0.5 -0.2153953634886357
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 126 distance computations.
rbox 10 D3 | qhull Qb1:0B1:0 d Tcv Q8
Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 14
Statistics for: rbox 10 D3 | qhull Qb1:0B1:0 d Tcv Q8
Number of points processed: 10
Number of hyperplanes created: 32
Number of facets in hull: 16
Number of distance tests for qhull: 62
CPU seconds to compute hull (after input): 0
QH7077 qhull input warning: no outer plane check ('Q5') or no processing of
near-inside points ('Q8'). Verify may report that a point is outside
of a facet.
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 140 distance computations.
rbox 10 D3 | qhull Qb1:0B1:0B2:0 d Tcv Q8
Delaunay triangulation by the convex hull of 10 points in 3-d:
Number of input sites: 10
Number of Delaunay regions: 14
Statistics for: rbox 10 D3 | qhull Qb1:0B1:0B2:0 d Tcv Q8
Number of points processed: 10
Number of hyperplanes created: 32
Number of facets in hull: 16
Number of distance tests for qhull: 62
CPU seconds to compute hull (after input): 0
QH7077 qhull input warning: no outer plane check ('Q5') or no processing of
near-inside points ('Q8'). Verify may report that a point is outside
of a facet.
Output completed. Verifying that all points are below 2e-015 of
all facets. Will make 140 distance computations.
rbox 10 D3 | qhull Qb1:0 d Tcv
Delaunay triangulation by the convex hull of 10 points in 4-d:
Number of input sites: 10
Number of Delaunay regions: 18
Statistics for: rbox 10 D3 | qhull Qb1:0 d Tcv
Number of points processed: 10
Number of hyperplanes created: 44
Number of facets in hull: 27
Number of distance tests for qhull: 67
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.9e-015 of
all facets. Will make 180 distance computations.
rbox 10 D3 | qhull Qb1:0B1:0 Tcv
Convex hull of 10 points in 2-d:
Number of vertices: 4
Number of facets: 4
Statistics for: rbox 10 D3 | qhull Qb1:0B1:0 Tcv
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 49
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 1.3e-015 of
all facets. Will make 40 distance computations.
echo "== next command will error ${d:-`date`} =="
date
-== next command will error Tue Jan 24 20:16:53 EST 2012 ==
+== next command will error Sun Aug 30 22:24:36 EDT 2015 ==
rbox 10 D2 | qhull Qb1:1B1:1 Tcv
QH6154 qhull precision error: initial facet 1 is coplanar with the interior point
ERRONEOUS FACET:
- f1
- flags: bottom simplicial flipped
- normal: 0 1
- offset: -1
- vertices: p4(v1) p1(v0)
- neighboring facets: f2 f3
While executing: rbox 10 D2 | qhull Qb1:1B1:1 Tcv
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 Qbound-dim-low 1 1 QBound-dim-high 1 1
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 Qbound-dim-low 1 1 QBound-dim-high 1 1
Tcheck-frequently Tverify _pre-merge _zero-centrum _max-width 0.81
Error-roundoff 8.6e-016 _one-merge 4.3e-015 _near-inside 2.1e-014
Visible-distance 1.7e-015 U-coplanar-distance 1.7e-015
Width-outside 3.4e-015 _wide-facet 1e-014
-precision problems (corrected unless 'Q0' or an error)
- 2 flipped facets
-
The input to qhull appears to be less than 2 dimensional, or a
computation has overflowed.
Qhull could not construct a clearly convex simplex from points:
- p0(v2): -0.022 1
- p4(v1): 0.38 1
- p1(v0): -0.43 1
The center point is coplanar with a facet, or a vertex is coplanar
with a neighboring facet. The maximum round off error for
computing distances is 8.6e-016. The center point, facets and distances
to the center point are as follows:
center point -0.02391 1
facet p4 p1 distance= 0
facet p0 p1 distance= 0
facet p0 p4 distance= 0
These points either have a maximum or minimum x-coordinate, or
they maximize the determinant for k coordinates. Trial points
are first selected from points that maximize a coordinate.
The min and max coordinates for each dimension are:
0: -0.4285 0.379 difference= 0.8076
1: 1 1 difference= 0
If the input should be full dimensional, you have several options that
may determine an initial simplex:
- use 'QJ' to joggle the input and make it full dimensional
- use 'QbB' to scale the points to the unit cube
- use 'QR0' to randomly rotate the input for different maximum points
- use 'Qs' to search all points for the initial simplex
- use 'En' to specify a maximum roundoff error less than 8.6e-016.
- trace execution with 'T3' to see the determinant for each point.
If the input is lower dimensional:
- use 'QJ' to joggle the input and make it full dimensional
- use 'Qbk:0Bk:0' to delete coordinate k from the input. You should
pick the coordinate with the least range. The hull will have the
correct topology.
- determine the flat containing the points, rotate the points
into a coordinate plane, and delete the other coordinates.
- add one or more points to make the input full dimensional.
rbox 200 L20 D2 t | qhull FO Tcv C-0
Convex hull of 200 points in 2-d:
Number of vertices: 200
Number of facets: 200
-Statistics for: rbox 200 L20 D2 t1327454213 | qhull FO Tcv C-0
+Statistics for: rbox 200 L20 D2 t1440987876 | qhull FO Tcv C-0
Number of points processed: 200
Number of hyperplanes created: 398
- Number of distance tests for qhull: 2125
+ Number of distance tests for qhull: 2053
CPU seconds to compute hull (after input): 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 Tcheck-frequently Tverify Centrum-premerge- 0
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 Tcheck-frequently Tverify Centrum-premerge- 0
_zero-centrum _max-width 1 Error-roundoff 3.4e-016 _one-merge 1.7e-015
_near-inside 8.5e-015 Visible-distance 6.8e-016
U-coplanar-distance 6.8e-016 Width-outside 1.4e-015 _wide-facet 4.1e-015
Output completed. Verifying that all points are below 1e-015 of
all facets. Will make 40000 distance computations.
rbox 1000 L20 t | qhull FO Tcv C-0
Convex hull of 1000 points in 3-d:
- Number of vertices: 50
- Number of facets: 96
+ Number of vertices: 46
+ Number of facets: 88
-Statistics for: rbox 1000 L20 t1327454213 | qhull FO Tcv C-0
+Statistics for: rbox 1000 L20 t1440987876 | qhull FO Tcv C-0
- Number of points processed: 71
- Number of hyperplanes created: 286
- Number of distance tests for qhull: 13384
+ Number of points processed: 58
+ Number of hyperplanes created: 231
+ Number of distance tests for qhull: 13755
CPU seconds to compute hull (after input): 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 Tcheck-frequently Tverify Centrum-premerge- 0
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 Tcheck-frequently Tverify Centrum-premerge- 0
_zero-centrum _max-width 1 Error-roundoff 6.9e-016 _one-merge 4.9e-015
_near-inside 2.4e-014 Visible-distance 1.4e-015
U-coplanar-distance 1.4e-015 Width-outside 2.8e-015 _wide-facet 8.3e-015
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 96000 distance computations.
+all facets. Will make 88000 distance computations.
rbox 200 L20 D4 t | qhull FO Tcv C-0
Convex hull of 200 points in 4-d:
- Number of vertices: 54
- Number of facets: 243
+ Number of vertices: 55
+ Number of facets: 244
-Statistics for: rbox 200 L20 D4 t1327454213 | qhull FO Tcv C-0
+Statistics for: rbox 200 L20 D4 t1440987876 | qhull FO Tcv C-0
- Number of points processed: 66
- Number of hyperplanes created: 772
- Number of distance tests for qhull: 6317
+ Number of points processed: 62
+ Number of hyperplanes created: 656
+ Number of distance tests for qhull: 6136
CPU seconds to compute hull (after input): 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 Tcheck-frequently Tverify Centrum-premerge- 0
- _zero-centrum _max-width 1 Error-roundoff 1e-015 _one-merge 9.1e-015
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 Tcheck-frequently Tverify Centrum-premerge- 0
+ _zero-centrum _max-width 0.99 Error-roundoff 1e-015 _one-merge 9e-015
_near-inside 4.5e-014 Visible-distance 6e-015 U-coplanar-distance 6e-015
Width-outside 1.2e-014 _wide-facet 3.6e-014
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 48600 distance computations.
+all facets. Will make 48800 distance computations.
rbox 200 L20 D5 t | qhull FO Tcv Qx
Convex hull of 200 points in 5-d:
- Number of vertices: 96
+ Number of vertices: 98
Number of facets: 1366
-Statistics for: rbox 200 L20 D5 t1327454213 | qhull FO Tcv Qx
+Statistics for: rbox 200 L20 D5 t1440987876 | qhull FO Tcv Qx
- Number of points processed: 117
- Number of hyperplanes created: 5545
- Number of distance tests for qhull: 21165
+ Number of points processed: 122
+ Number of hyperplanes created: 5142
+ Number of distance tests for qhull: 19745
CPU seconds to compute hull (after input): 0.015
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 Tcheck-frequently Tverify Qxact-merge _zero-centrum
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510144713 Tcheck-frequently Tverify Qxact-merge _zero-centrum
_max-width 1 Error-roundoff 1.4e-015 _one-merge 1.5e-014
_near-inside 7.5e-014 Visible-distance 8.2e-015
U-coplanar-distance 8.2e-015 Width-outside 1.6e-014 _wide-facet 4.9e-014
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 273200 distance computations.
rbox 1000 W1e-3 s D2 t | qhull d FO Tcv Qu Q0
Furthest-site Delaunay triangulation by the convex hull of 1000 points in 3-d:
Number of input sites: 1000
- Number of Delaunay regions: 260
+ Number of Delaunay regions: 270
-Statistics for: rbox 1000 W1e-3 s D2 t1327454213 | qhull d FO Tcv Qu Q0
+Statistics for: rbox 1000 W1e-3 s D2 t1440987877 | qhull d FO Tcv Qu Q0
Number of points processed: 1000
- Number of hyperplanes created: 4637
+ Number of hyperplanes created: 4478
Number of facets in hull: 1996
- Number of distance tests for qhull: 26132
+ Number of distance tests for qhull: 26841
CPU seconds to compute hull (after input): 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 delaunay Tcheck-frequently Tverify QupperDelaunay
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510161520 delaunay Tcheck-frequently Tverify QupperDelaunay
Q0-no-premerge Pgood _max-width 1 Error-roundoff 6.9e-016
Visible-distance 6.9e-016 U-coplanar-distance 6.9e-016
Width-outside 1.4e-015 _wide-facet 4.2e-015
Output completed. Verifying that all points are below 2.1e-015 of
-all facets. Will make 260000 distance computations.
+all facets. Will make 270000 distance computations.
rbox 1000 W1e-3 s D2 t | qhull d FO Tcv Qu C-0
Furthest-site Delaunay triangulation by the convex hull of 1000 points in 3-d:
Number of input sites: 1000
- Number of Delaunay regions: 260
+ Number of Delaunay regions: 270
-Statistics for: rbox 1000 W1e-3 s D2 t1327454213 | qhull d FO Tcv Qu C-0
+Statistics for: rbox 1000 W1e-3 s D2 t1440987877 | qhull d FO Tcv Qu C-0
Number of points processed: 1000
- Number of hyperplanes created: 4637
+ Number of hyperplanes created: 4478
Number of facets in hull: 1996
- Number of distance tests for qhull: 26132
+ Number of distance tests for qhull: 26841
CPU seconds to compute hull (after input): 0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 delaunay Tcheck-frequently Tverify QupperDelaunay
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510161520 delaunay Tcheck-frequently Tverify QupperDelaunay
Centrum-premerge- 0 _zero-centrum Pgood _max-width 1
Error-roundoff 6.9e-016 _one-merge 4.9e-015 _near-inside 2.4e-014
Visible-distance 1.4e-015 U-coplanar-distance 1.4e-015
Width-outside 2.8e-015 _wide-facet 8.3e-015
Output completed. Verifying that all points are below 2.1e-015 of
-all facets. Will make 260000 distance computations.
+all facets. Will make 270000 distance computations.
echo === check joggle and TRn ${d:-`date`}
date
-=== check joggle and TRn Tue Jan 24 20:16:53 EST 2012
+=== check joggle and TRn Sun Aug 30 22:24:37 EDT 2015
rbox 100 W0 | qhull QJ1e-14 Qc TR100 Tv
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 15
Number of coplanar points: 4
Number of facets: 25
Statistics for: rbox 100 W0 | qhull QJ1e-14 Qc TR100 Tv
Number of points processed: 15
Number of hyperplanes created: 11270
Number of distance tests for qhull: 120689
CPU seconds to compute hull (after input): 0.015
Percentage of runs with precision errors: 100.0
precision problems (corrected unless 'Q0' or an error)
100 coplanar horizon facets for new vertices
400 coplanar points during partitioning
rbox 100 W0 | qhull QJ1e-13 Qc TR100 Tv
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 28
Number of coplanar points: 12
Number of facets: 50
Statistics for: rbox 100 W0 | qhull QJ1e-13 Qc TR100 Tv
Number of points processed: 28
Number of hyperplanes created: 24800
Number of distance tests for qhull: 197857
CPU seconds to compute hull (after input): 0.031
Percentage of runs with precision errors: 63.0
precision problems (corrected unless 'Q0' or an error)
10 coplanar half ridges in output
53 coplanar horizon facets for new vertices
119 coplanar points during partitioning
rbox 100 W0 | qhull QJ1e-12 Qc TR100 Tv
At a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.
Convex hull of 100 points in 3-d:
Number of vertices: 40
Number of coplanar points: 16
Number of facets: 75
Statistics for: rbox 100 W0 | qhull QJ1e-12 Qc TR100 Tv
Number of points processed: 40
Number of hyperplanes created: 29205
Number of distance tests for qhull: 217398
- CPU seconds to compute hull (after input): 0.031
+ CPU seconds to compute hull (after input): 0.046
Percentage of runs with precision errors: 8.0
precision problems (corrected unless 'Q0' or an error)
2 coplanar half ridges in output
6 coplanar horizon facets for new vertices
17 coplanar points during partitioning
rbox 100 W0 | qhull QJ1e-11 Qc TR100 Tv
Convex hull of 100 points in 3-d:
Number of vertices: 66
Number of coplanar points: 34
Number of facets: 128
Statistics for: rbox 100 W0 | qhull QJ1e-11 Qc TR100 Tv
Number of points processed: 75
Number of hyperplanes created: 29630
Number of distance tests for qhull: 219104
CPU seconds to compute hull (after input): 0.031
Percentage of runs with precision errors: 0.0
precision problems (corrected unless 'Q0' or an error)
3 coplanar points during partitioning
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 12800 distance computations.
rbox 100 W0 | qhull QJ1e-10 Qc TR100 Tv
Convex hull of 100 points in 3-d:
Number of vertices: 66
Number of coplanar points: 34
Number of facets: 128
Statistics for: rbox 100 W0 | qhull QJ1e-10 Qc TR100 Tv
Number of points processed: 75
Number of hyperplanes created: 29636
Number of distance tests for qhull: 218960
CPU seconds to compute hull (after input): 0.031
Percentage of runs with precision errors: 0.0
Output completed. Verifying that all points are below 2.1e-015 of
all facets. Will make 12800 distance computations.
rbox 100 | qhull d QJ Qb0:1e4 QB0:1e5 Qb1:1e4 QB1:1e6 Qb2:1e5 QB2:1e7 FO Tv
Delaunay triangulation by the convex hull of 100 points in 4-d:
Number of input sites: 100
Number of Delaunay regions: 488
Statistics for: rbox 100 | qhull d QJ Qb0:1e4 QB0:1e5 Qb1:1e4 QB1:1e6 Qb2:1e5 QB2:1e7 FO Tv
Number of points processed: 100
Number of hyperplanes created: 1578
Number of facets in hull: 560
Number of distance tests for qhull: 3924
CPU seconds to compute hull (after input): 0.015
Input joggled by: 6.7e+003
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 delaunay Qbound-dim-low 0 1e+004 QBound-dim-high 0 1e+005
- Qbound-dim-low 1 1e+004 QBound-dim-high 1 1e+006 Qbound-dim-low 2 1e+005
- QBound-dim-high 2 1e+007 Tverify Pgood _run 1 QJoggle 6.7e+003
- _joggle-seed 16807 _max-width 1e+014 Error-roundoff 0.11
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510161520 delaunay Qbound-dim-low 0 1e+004
+ QBound-dim-high 0 1e+005 Qbound-dim-low 1 1e+004 QBound-dim-high 1 1e+006
+ Qbound-dim-low 2 1e+005 QBound-dim-high 2 1e+007 Tverify Pgood _run 1
+ QJoggle 6.7e+003 _joggle-seed 16807 _max-width 1e+014 Error-roundoff 0.11
Visible-distance 0.11 U-coplanar-distance 0.11 Width-outside 0.23
_wide-facet 0.68
Output completed. Verifying that all points are below 0.34 of
all facets. Will make 48800 distance computations.
echo === check precision options ${d:-`date`}
date
-=== check precision options Tue Jan 24 20:16:53 EST 2012
+=== check precision options Sun Aug 30 22:24:37 EDT 2015
rbox 100 D3 s | qhull E0.01 Qx Tcv FO
Convex hull of 100 points in 3-d:
Number of vertices: 45
Number of facets: 42
Number of non-simplicial facets: 28
Statistics for: rbox 100 D3 s | qhull E0.01 Qx Tcv FO
Number of points processed: 45
Number of hyperplanes created: 160
Number of distance tests for qhull: 3992
Number of distance tests for merging: 2006
Number of distance tests for checking: 1937
Number of merged facets: 57
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.048 (0.6x)
Maximum distance of vertex below facet: -0.072 (0.9x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315349209 Distance-roundoff 0.01 Qxact-merge Tcheck-frequently
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510161520 Distance-roundoff 0.01 Qxact-merge Tcheck-frequently
Tverify _zero-centrum _max-width 0.98 _one-merge 0.07 _near-inside 0.35
Visible-distance 0.02 U-coplanar-distance 0.02 Width-outside 0.04
_wide-facet 0.12
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 4200 distance computations.
rbox 100 D3 W1e-1 | qhull W1e-3 Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 33
Number of facets: 62
Statistics for: rbox 100 D3 W1e-1 | qhull W1e-3 Tcv
Number of points processed: 37
Number of hyperplanes created: 170
Number of distance tests for qhull: 1580
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.00084
Output completed. Verifying that all points are below outer planes of
all facets. Will make 6200 distance computations.
rbox 100 D3 W1e-1 | qhull W1e-2 Tcv Q0
Convex hull of 100 points in 3-d:
Number of vertices: 28
Number of facets: 52
Statistics for: rbox 100 D3 W1e-1 | qhull W1e-2 Tcv Q0
Number of points processed: 29
Number of hyperplanes created: 128
Number of distance tests for qhull: 1442
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
22 coplanar points during partitioning
Output completed. Verifying that all points are below 0.0097 of
all facets. Will make 5200 distance computations.
rbox 100 D3 W1e-1 | qhull W1e-2 Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 29
Number of facets: 54
Statistics for: rbox 100 D3 W1e-1 | qhull W1e-2 Tcv
Number of points processed: 30
Number of hyperplanes created: 132
Number of distance tests for qhull: 1768
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.0057
Output completed. Verifying that all points are below outer planes of
all facets. Will make 5400 distance computations.
rbox 100 D3 W1e-1 | qhull W1e-1 Tcv
Convex hull of 100 points in 3-d:
Number of vertices: 13
Number of facets: 22
Statistics for: rbox 100 D3 W1e-1 | qhull W1e-1 Tcv
Number of points processed: 13
Number of hyperplanes created: 46
Number of distance tests for qhull: 2521
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.098
Output completed. Verifying that all points are below outer planes of
all facets. Will make 2200 distance computations.
rbox 15 D2 P0 P1e-14,1e-14 | qhull d Quc Tcv
Furthest-site Delaunay triangulation by the convex hull of 17 points in 3-d:
Number of input sites: 17
Number of Delaunay regions: 5
Statistics for: rbox 15 D2 P0 P1e-14,1e-14 | qhull d Quc Tcv
Number of points processed: 17
Number of hyperplanes created: 64
Number of facets in hull: 28
Number of distance tests for qhull: 142
Number of distance tests for merging: 527
Number of distance tests for checking: 194
Number of merged facets: 7
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 1.6e-015 (0.3x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 85 distance computations.
rbox 15 D3 P0 P1e-12,1e-14,1e-14 | qhull d Qcu Tcv
Furthest-site Delaunay triangulation by the convex hull of 17 points in 4-d:
Number of input sites: 17
Number of Delaunay regions: 14
Statistics for: rbox 15 D3 P0 P1e-12,1e-14,1e-14 | qhull d Qcu Tcv
Number of points processed: 17
Number of hyperplanes created: 124
Number of facets in hull: 60
Number of distance tests for qhull: 225
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below 2.8e-015 of
all facets. Will make 238 distance computations.
rbox 1000 s D3 | qhull C-0.01 Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 107
Number of coplanar points: 893
Number of facets: 96
Number of non-simplicial facets: 77
Statistics for: rbox 1000 s D3 | qhull C-0.01 Tcv Qc
Number of points processed: 112
Number of hyperplanes created: 449
Number of distance tests for qhull: 64526
Number of distance tests for merging: 8425
Number of distance tests for checking: 23411
Number of merged facets: 256
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96000 distance computations.
rbox 1000 s D3 | qhull C-0.01 V0 Qc Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 120
Number of coplanar points: 880
Number of facets: 82
Number of non-simplicial facets: 71
Statistics for: rbox 1000 s D3 | qhull C-0.01 V0 Qc Tcv
Number of points processed: 445
Number of hyperplanes created: 2451
Number of distance tests for qhull: 172077
Number of distance tests for merging: 52430
Number of distance tests for checking: 19885
Number of merged facets: 1741
- CPU seconds to compute hull (after input): 0.031
+ CPU seconds to compute hull (after input): 0.016
Maximum distance of point above facet: 0.032 (1.1x)
Maximum distance of vertex below facet: -0.064 (2.1x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 82000 distance computations.
rbox 1000 s D3 | qhull C-0.01 U0 Qc Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 107
Number of coplanar points: 893
Number of facets: 98
Number of non-simplicial facets: 77
Statistics for: rbox 1000 s D3 | qhull C-0.01 U0 Qc Tcv
Number of points processed: 112
Number of hyperplanes created: 497
Number of distance tests for qhull: 64717
Number of distance tests for merging: 9106
Number of distance tests for checking: 23621
Number of merged facets: 254
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 98000 distance computations.
rbox 1000 s D3 | qhull C-0.01 V0 Qcm Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 106
Number of coplanar points: 894
Number of facets: 94
Number of non-simplicial facets: 71
Statistics for: rbox 1000 s D3 | qhull C-0.01 V0 Qcm Tcv
Number of points processed: 114
Number of hyperplanes created: 597
Number of distance tests for qhull: 54389
Number of distance tests for merging: 10179
Number of distance tests for checking: 18597
Number of merged facets: 288
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.025 (0.8x)
Maximum distance of vertex below facet: -0.07 (2.3x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 94000 distance computations.
rbox 1000 s D3 | qhull C-0.01 Qcm Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 103
Number of coplanar points: 897
Number of facets: 96
Number of non-simplicial facets: 69
Statistics for: rbox 1000 s D3 | qhull C-0.01 Qcm Tcv
Number of points processed: 106
Number of hyperplanes created: 434
Number of distance tests for qhull: 64355
Number of distance tests for merging: 7947
Number of distance tests for checking: 23460
Number of merged facets: 234
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.022 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96000 distance computations.
rbox 1000 s D3 | qhull C-0.01 Q1 FO Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 105
Number of coplanar points: 895
Number of facets: 94
Number of non-simplicial facets: 70
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q1 FO Tcv Qc
Number of points processed: 110
Number of hyperplanes created: 457
Number of distance tests for qhull: 66717
Number of distance tests for merging: 8730
Number of distance tests for checking: 23168
Number of merged facets: 258
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q1-no-angle-sort Tcheck-frequently
- Tverify Qcoplanar-keep _max-width 1 Error-roundoff 6.9e-016
- _one-merge 0.03 _near-inside 0.15 Visible-distance 0.01
- U-coplanar-distance 0.01 Width-outside 0.02 _wide-facet 0.06
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q1-no-angle-sort
+ Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
+ Error-roundoff 6.9e-016 _one-merge 0.03 _near-inside 0.15
+ Visible-distance 0.01 U-coplanar-distance 0.01 Width-outside 0.02
+ _wide-facet 0.06
Output completed. Verifying that all points are below outer planes of
all facets. Will make 94000 distance computations.
rbox 1000 s D3 | qhull C-0.01 Q2 FO Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 106
Number of coplanar points: 894
Number of facets: 91
Number of non-simplicial facets: 74
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q2 FO Tcv Qc
Number of points processed: 112
Number of hyperplanes created: 454
Number of distance tests for qhull: 64909
Number of distance tests for merging: 8602
Number of distance tests for checking: 22777
Number of merged facets: 267
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.049 (1.6x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q2-no-merge-independent
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q2-no-merge-independent
Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.03 _near-inside 0.15
Visible-distance 0.01 U-coplanar-distance 0.01 Width-outside 0.02
_wide-facet 0.06
Output completed. Verifying that all points are below outer planes of
all facets. Will make 91000 distance computations.
rbox 1000 s D3 | qhull C-0.01 Q3 FO Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 112
Number of coplanar points: 888
Number of facets: 95
Number of non-simplicial facets: 78
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q3 FO Tcv Qc
Number of points processed: 112
Number of hyperplanes created: 453
Number of distance tests for qhull: 64248
Number of distance tests for merging: 8529
Number of distance tests for checking: 23283
Number of merged facets: 260
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q3-no-merge-vertices
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q3-no-merge-vertices
Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.03 _near-inside 0.15
Visible-distance 0.01 U-coplanar-distance 0.01 Width-outside 0.02
_wide-facet 0.06
Output completed. Verifying that all points are below outer planes of
all facets. Will make 95000 distance computations.
rbox 1000 s D3 | qhull C-0.01 Q4 FO Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 107
Number of coplanar points: 893
Number of facets: 96
Number of non-simplicial facets: 77
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q4 FO Tcv Qc
Number of points processed: 112
Number of hyperplanes created: 449
Number of distance tests for qhull: 64526
Number of distance tests for merging: 8425
Number of distance tests for checking: 23411
Number of merged facets: 256
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q4-avoid-old-into-new
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q4-avoid-old-into-new
Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.03 _near-inside 0.15
Visible-distance 0.01 U-coplanar-distance 0.01 Width-outside 0.02
_wide-facet 0.06
Output completed. Verifying that all points are below outer planes of
all facets. Will make 96000 distance computations.
echo === this may generate an error ${d:-`date`}
date
-=== this may generate an error Tue Jan 24 20:16:54 EST 2012
+=== this may generate an error Sun Aug 30 22:24:38 EDT 2015
rbox 1000 s D3 | qhull C-0.01 Q5 FO Tcv
Convex hull of 1000 points in 3-d:
Number of vertices: 107
Number of facets: 96
Number of non-simplicial facets: 77
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q5 FO Tcv
Number of points processed: 112
Number of hyperplanes created: 449
Number of distance tests for qhull: 38064
Number of distance tests for merging: 8425
Number of distance tests for checking: 0
Number of merged facets: 256
CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.022 (0.7x)
Maximum distance of vertex below facet: -0.035 (1.2x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q5-no-check-outer
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q5-no-check-outer
Tcheck-frequently Tverify _max-width 1 Error-roundoff 6.9e-016
_one-merge 0.03 Visible-distance 0.01 U-coplanar-distance 0.01
Width-outside 0.02 _wide-facet 0.06
QH7077 qhull input warning: no outer plane check ('Q5') or no processing of
near-inside points ('Q8'). Verify may report that a point is outside
of a facet.
Output completed. Verifying that all points are below 0.022 of
all facets. Will make 96000 distance computations.
echo === this should generate an error ${d:-`date`}
date
-=== this should generate an error Tue Jan 24 20:16:54 EST 2012
+=== this should generate an error Sun Aug 30 22:24:38 EDT 2015
rbox 1000 s D3 | qhull C-0.01 Q6 FO Po Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 114
Number of coplanar points: 886
Number of facets: 182
Number of non-simplicial facets: 40
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q6 FO Po Tcv Qc
Number of points processed: 114
Number of hyperplanes created: 447
Number of distance tests for qhull: 53157
Number of distance tests for merging: 3458
Number of distance tests for checking: 27470
Number of merged facets: 88
- CPU seconds to compute hull (after input): 0
+ CPU seconds to compute hull (after input): 0.015
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.009 (0.3x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q6-no-concave-merge Poutput-forced
- Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q6-no-concave-merge
+ Poutput-forced Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.03 _near-inside 0.15
Visible-distance 0.01 U-coplanar-distance 0.01 Width-outside 0.02
_wide-facet 0.06
QH6117 qhull precision error: f324 is concave to f325. Centrum of f324 is 0.004134 above f325
QH6117 qhull precision error: f325 is concave to f324. Centrum of f325 is 0.001027 above f324
rbox 1000 s D3 | qhull C-0.01 Q7 FO Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 100
Number of coplanar points: 900
Number of facets: 94
Number of non-simplicial facets: 73
Statistics for: rbox 1000 s D3 | qhull C-0.01 Q7 FO Tcv Qc
Number of points processed: 103
Number of hyperplanes created: 448
Number of distance tests for qhull: 70481
Number of distance tests for merging: 8005
Number of distance tests for checking: 21158
Number of merged facets: 233
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.042 (1.4x)
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315366016 Centrum-premerge- 0.01 Q7-no-breadth-first
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510178327 Centrum-premerge- 0.01 Q7-no-breadth-first
Tcheck-frequently Tverify Qcoplanar-keep _max-width 1
Error-roundoff 6.9e-016 _one-merge 0.03 _near-inside 0.15
Visible-distance 0.01 U-coplanar-distance 0.01 Width-outside 0.02
_wide-facet 0.06
Output completed. Verifying that all points are below outer planes of
all facets. Will make 94000 distance computations.
rbox 1000 s D3 | qhull C-0.01 Qx Tcv Qc
Convex hull of 1000 points in 3-d:
Number of vertices: 114
Number of coplanar points: 886
Number of facets: 103
Number of non-simplicial facets: 77
Statistics for: rbox 1000 s D3 | qhull C-0.01 Qx Tcv Qc
Number of points processed: 114
Number of hyperplanes created: 447
Number of distance tests for qhull: 90887
Number of distance tests for merging: 5483
Number of distance tests for checking: 20583
Number of merged facets: 167
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
Maximum distance of point above facet: 0.02 (0.7x)
Maximum distance of vertex below facet: -0.034 (1.1x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 103000 distance computations.
echo === this may generate an error e.g., t1263080158 ${d:-`date`}
date
-=== this may generate an error e.g., t1263080158 Tue Jan 24 20:16:54 EST 2012
+=== this may generate an error e.g., t1263080158 Sun Aug 30 22:24:38 EDT 2015
rbox 100 s D3 t | qhull R1e-3 Tcv Qc
Convex hull of 100 points in 3-d:
- Number of vertices: 99
- Number of coplanar points: 1
+ Number of vertices: 100
Number of facets: 170
Number of non-simplicial facets: 22
-Statistics for: rbox 100 s D3 t1327454214 | qhull R1e-3 Tcv Qc
+Statistics for: rbox 100 s D3 t1440987878 | qhull R1e-3 Tcv Qc
Number of points processed: 100
- Number of hyperplanes created: 486
- Number of distance tests for qhull: 1750
- Number of distance tests for merging: 3528
- Number of distance tests for checking: 1354
- Number of merged facets: 45
- CPU seconds to compute hull (after input): 0.015
- Maximum distance of point above facet: 0.0019 (0.5x)
- Maximum distance of vertex below facet: -0.004 (1.0x)
+ Number of hyperplanes created: 463
+ Number of distance tests for qhull: 1565
+ Number of distance tests for merging: 3905
+ Number of distance tests for checking: 1378
+ Number of merged facets: 57
+ CPU seconds to compute hull (after input): 0
+ Maximum distance of point above facet: 0.0016 (0.4x)
+ Maximum distance of vertex below facet: -0.007 (1.8x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 17000 distance computations.
rbox 100 s D3 t | qhull R1e-2 Tcv Qc
Convex hull of 100 points in 3-d:
- Number of vertices: 62
- Number of coplanar points: 38
- Number of facets: 61
- Number of non-simplicial facets: 37
+ Number of vertices: 63
+ Number of coplanar points: 37
+ Number of facets: 62
+ Number of non-simplicial facets: 44
-Statistics for: rbox 100 s D3 t1327454214 | qhull R1e-2 Tcv Qc
+Statistics for: rbox 100 s D3 t1440987878 | qhull R1e-2 Tcv Qc
- Number of points processed: 64
- Number of hyperplanes created: 273
- Number of distance tests for qhull: 3715
- Number of distance tests for merging: 4249
- Number of distance tests for checking: 2058
- Number of merged facets: 120
+ Number of points processed: 67
+ Number of hyperplanes created: 277
+ Number of distance tests for qhull: 3281
+ Number of distance tests for merging: 4590
+ Number of distance tests for checking: 2142
+ Number of merged facets: 134
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.028 (0.7x)
- Maximum distance of vertex below facet: -0.091 (2.3x)
+ Maximum distance of point above facet: 0.029 (0.7x)
+ Maximum distance of vertex below facet: -0.051 (1.3x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 6100 distance computations.
+all facets. Will make 6200 distance computations.
rbox 500 s D3 t | qhull R0.05 A-1 Tcv Qc
Convex hull of 500 points in 3-d:
- Number of vertices: 22
- Number of coplanar points: 478
- Number of facets: 17
- Number of non-simplicial facets: 15
+ Number of vertices: 21
+ Number of coplanar points: 479
+ Number of facets: 18
+ Number of non-simplicial facets: 14
-Statistics for: rbox 500 s D3 t1327454214 | qhull R0.05 A-1 Tcv Qc
+Statistics for: rbox 500 s D3 t1440987878 | qhull R0.05 A-1 Tcv Qc
- Number of points processed: 24
- Number of hyperplanes created: 80
- Number of distance tests for qhull: 22361
- Number of distance tests for merging: 1531
- Number of distance tests for checking: 7408
- Number of merged facets: 49
+ Number of points processed: 23
+ Number of hyperplanes created: 78
+ Number of distance tests for qhull: 23693
+ Number of distance tests for merging: 1482
+ Number of distance tests for checking: 7850
+ Number of merged facets: 45
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.14 (0.2x)
- Maximum distance of vertex below facet: -0.26 (0.4x)
+ Maximum distance of point above facet: 0.13 (0.2x)
+ Maximum distance of vertex below facet: -0.25 (0.4x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 8500 distance computations.
+all facets. Will make 9000 distance computations.
rbox 100 W0 D3 t | qhull R1e-3 Tcv Qc
Convex hull of 100 points in 3-d:
- Number of vertices: 37
- Number of coplanar points: 63
- Number of facets: 46
- Number of non-simplicial facets: 8
+ Number of vertices: 43
+ Number of coplanar points: 57
+ Number of facets: 52
+ Number of non-simplicial facets: 10
-Statistics for: rbox 100 W0 D3 t1327454214 | qhull R1e-3 Tcv Qc
+Statistics for: rbox 100 W0 D3 t1440987878 | qhull R1e-3 Tcv Qc
- Number of points processed: 42
- Number of hyperplanes created: 142
- Number of distance tests for qhull: 2042
- Number of distance tests for merging: 1656
- Number of distance tests for checking: 1067
- Number of merged facets: 41
- CPU seconds to compute hull (after input): 0.015
- Maximum distance of point above facet: 0.0025 (0.6x)
- Maximum distance of vertex below facet: -0.0051 (1.3x)
+ Number of points processed: 53
+ Number of hyperplanes created: 185
+ Number of distance tests for qhull: 1895
+ Number of distance tests for merging: 2273
+ Number of distance tests for checking: 1184
+ Number of merged facets: 56
+ CPU seconds to compute hull (after input): 0
+ Maximum distance of point above facet: 0.0029 (0.7x)
+ Maximum distance of vertex below facet: -0.0049 (1.2x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 4600 distance computations.
+all facets. Will make 5200 distance computations.
rbox 100 W0 D3 t | qhull R1e-3 Qx Tcv Qc
Convex hull of 100 points in 3-d:
- Number of vertices: 38
- Number of coplanar points: 62
- Number of facets: 47
- Number of non-simplicial facets: 9
+ Number of vertices: 43
+ Number of coplanar points: 57
+ Number of facets: 52
+ Number of non-simplicial facets: 10
-Statistics for: rbox 100 W0 D3 t1327454214 | qhull R1e-3 Qx Tcv Qc
+Statistics for: rbox 100 W0 D3 t1440987878 | qhull R1e-3 Qx Tcv Qc
- Number of points processed: 44
- Number of hyperplanes created: 147
- Number of distance tests for qhull: 2938
- Number of distance tests for merging: 1582
- Number of distance tests for checking: 1068
- Number of merged facets: 42
+ Number of points processed: 55
+ Number of hyperplanes created: 189
+ Number of distance tests for qhull: 2398
+ Number of distance tests for merging: 1922
+ Number of distance tests for checking: 1187
+ Number of merged facets: 56
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.0017 (0.4x)
- Maximum distance of vertex below facet: -0.0048 (1.2x)
+ Maximum distance of point above facet: 0.0021 (0.5x)
+ Maximum distance of vertex below facet: -0.0052 (1.3x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 4700 distance computations.
+all facets. Will make 5200 distance computations.
rbox 100 W0 D3 t | qhull R1e-2 Tcv Qc
Convex hull of 100 points in 3-d:
Number of vertices: 27
Number of coplanar points: 73
- Number of facets: 27
- Number of non-simplicial facets: 12
+ Number of facets: 26
+ Number of non-simplicial facets: 10
-Statistics for: rbox 100 W0 D3 t1327454214 | qhull R1e-2 Tcv Qc
+Statistics for: rbox 100 W0 D3 t1440987878 | qhull R1e-2 Tcv Qc
- Number of points processed: 33
- Number of hyperplanes created: 108
- Number of distance tests for qhull: 2267
- Number of distance tests for merging: 1505
- Number of distance tests for checking: 1069
- Number of merged facets: 44
- CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.024 (0.6x)
- Maximum distance of vertex below facet: -0.031 (0.8x)
+ Number of points processed: 40
+ Number of hyperplanes created: 137
+ Number of distance tests for qhull: 3167
+ Number of distance tests for merging: 2293
+ Number of distance tests for checking: 1332
+ Number of merged facets: 72
+ CPU seconds to compute hull (after input): 0.015
+ Maximum distance of point above facet: 0.022 (0.5x)
+ Maximum distance of vertex below facet: -0.052 (1.3x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 2700 distance computations.
+all facets. Will make 2600 distance computations.
rbox 100 W0 D3 t | qhull R1e-2 Qx Tcv Qc
Convex hull of 100 points in 3-d:
- Number of vertices: 30
- Number of coplanar points: 70
- Number of facets: 30
- Number of non-simplicial facets: 11
+ Number of vertices: 31
+ Number of coplanar points: 69
+ Number of facets: 29
+ Number of non-simplicial facets: 12
-Statistics for: rbox 100 W0 D3 t1327454215 | qhull R1e-2 Qx Tcv Qc
+Statistics for: rbox 100 W0 D3 t1440987878 | qhull R1e-2 Qx Tcv Qc
- Number of points processed: 34
- Number of hyperplanes created: 111
- Number of distance tests for qhull: 2798
- Number of distance tests for merging: 1363
- Number of distance tests for checking: 1107
- Number of merged facets: 38
+ Number of points processed: 42
+ Number of hyperplanes created: 160
+ Number of distance tests for qhull: 3713
+ Number of distance tests for merging: 1727
+ Number of distance tests for checking: 1434
+ Number of merged facets: 57
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.025 (0.6x)
- Maximum distance of vertex below facet: -0.05 (1.3x)
+ Maximum distance of point above facet: 0.02 (0.5x)
+ Maximum distance of vertex below facet: -0.054 (1.4x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 3000 distance computations.
+all facets. Will make 2900 distance computations.
rbox 500 W0 D3 t | qhull R0.05 A-1 Tcv Qc
Convex hull of 500 points in 3-d:
- Number of vertices: 8
- Number of coplanar points: 492
- Number of facets: 6
+ Number of vertices: 9
+ Number of coplanar points: 491
+ Number of facets: 7
Number of non-simplicial facets: 6
-Statistics for: rbox 500 W0 D3 t1327454215 | qhull R0.05 A-1 Tcv Qc
+Statistics for: rbox 500 W0 D3 t1440987878 | qhull R0.05 A-1 Tcv Qc
Number of points processed: 15
- Number of hyperplanes created: 46
- Number of distance tests for qhull: 16005
- Number of distance tests for merging: 742
- Number of distance tests for checking: 3754
- Number of merged facets: 26
+ Number of hyperplanes created: 39
+ Number of distance tests for qhull: 15778
+ Number of distance tests for merging: 655
+ Number of distance tests for checking: 4219
+ Number of merged facets: 24
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.067 (0.1x)
- Maximum distance of vertex below facet: -0.17 (0.3x)
+ Maximum distance of point above facet: 0.14 (0.2x)
+ Maximum distance of vertex below facet: -0.12 (0.2x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 3000 distance computations.
+all facets. Will make 3500 distance computations.
rbox 500 W0 D3 t | qhull R0.05 Qx Tcv Qc
Convex hull of 500 points in 3-d:
- Number of vertices: 9
- Number of coplanar points: 491
+ Number of vertices: 10
+ Number of coplanar points: 490
Number of facets: 7
Number of non-simplicial facets: 6
-Statistics for: rbox 500 W0 D3 t1327454215 | qhull R0.05 Qx Tcv Qc
+Statistics for: rbox 500 W0 D3 t1440987878 | qhull R0.05 Qx Tcv Qc
- Number of points processed: 18
- Number of hyperplanes created: 45
- Number of distance tests for qhull: 22085
- Number of distance tests for merging: 596
- Number of distance tests for checking: 4091
- Number of merged facets: 31
+ Number of points processed: 16
+ Number of hyperplanes created: 34
+ Number of distance tests for qhull: 16739
+ Number of distance tests for merging: 453
+ Number of distance tests for checking: 4221
+ Number of merged facets: 23
CPU seconds to compute hull (after input): 0
- Maximum distance of point above facet: 0.14 (0.7x)
- Maximum distance of vertex below facet: -0.19 (0.9x)
+ Maximum distance of point above facet: 0.1 (0.5x)
+ Maximum distance of vertex below facet: -0.14 (0.7x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 3500 distance computations.
rbox 1000 W1e-20 t | qhull Tcv Qc
Convex hull of 1000 points in 3-d:
- Number of vertices: 76
- Number of coplanar points: 924
- Number of facets: 90
+ Number of vertices: 81
+ Number of coplanar points: 919
+ Number of facets: 95
Number of non-simplicial facets: 6
-Statistics for: rbox 1000 W1e-20 t1327454215 | qhull Tcv Qc
+Statistics for: rbox 1000 W1e-20 t1440987878 | qhull Tcv Qc
- Number of points processed: 91
- Number of hyperplanes created: 288
- Number of distance tests for qhull: 19728
- Number of distance tests for merging: 3852
- Number of distance tests for checking: 28894
- Number of merged facets: 88
+ Number of points processed: 93
+ Number of hyperplanes created: 309
+ Number of distance tests for qhull: 19631
+ Number of distance tests for merging: 4083
+ Number of distance tests for checking: 30755
+ Number of merged facets: 87
CPU seconds to compute hull (after input): 0
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 90000 distance computations.
+all facets. Will make 95000 distance computations.
rbox 1000 W1e-20 D4 t | qhull Tcv Qc
Convex hull of 1000 points in 4-d:
- Number of vertices: 270
- Number of coplanar points: 730
- Number of facets: 975
+ Number of vertices: 280
+ Number of coplanar points: 720
+ Number of facets: 1054
Number of non-simplicial facets: 8
-Statistics for: rbox 1000 W1e-20 D4 t1327454215 | qhull Tcv Qc
+Statistics for: rbox 1000 W1e-20 D4 t1440987878 | qhull Tcv Qc
- Number of points processed: 338
- Number of hyperplanes created: 4074
- Number of distance tests for qhull: 68477
- Number of distance tests for merging: 63566
- Number of distance tests for checking: 140180
- Number of merged facets: 1048
+ Number of points processed: 353
+ Number of hyperplanes created: 4517
+ Number of distance tests for qhull: 70679
+ Number of distance tests for merging: 68784
+ Number of distance tests for checking: 147214
+ Number of merged facets: 1045
CPU seconds to compute hull (after input): 0.078
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 975000 distance computations.
+all facets. Will make 1054000 distance computations.
rbox 500 W1e-20 D5 t | qhull Tv Qc
Convex hull of 500 points in 5-d:
- Number of vertices: 336
- Number of coplanar points: 164
- Number of facets: 5242
+ Number of vertices: 346
+ Number of coplanar points: 154
+ Number of facets: 5594
Number of non-simplicial facets: 10
-Statistics for: rbox 500 W1e-20 D5 t1327454215 | qhull Tv Qc
+Statistics for: rbox 500 W1e-20 D5 t1440987879 | qhull Tv Qc
- Number of points processed: 402
- Number of hyperplanes created: 27379
- Number of distance tests for qhull: 125805
- Number of distance tests for merging: 297315
- Number of distance tests for checking: 226312
- Number of merged facets: 3444
- CPU seconds to compute hull (after input): 0.109
+ Number of points processed: 391
+ Number of hyperplanes created: 25286
+ Number of distance tests for qhull: 121050
+ Number of distance tests for merging: 286335
+ Number of distance tests for checking: 238954
+ Number of merged facets: 2984
+ CPU seconds to compute hull (after input): 0.094
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 2621000 distance computations.
+all facets. Will make 2797000 distance computations.
rbox 100 W1e-20 D6 t | qhull Tv Qc
Convex hull of 100 points in 6-d:
Number of vertices: 100
- Number of facets: 5769
- Number of non-simplicial facets: 10
+ Number of facets: 5756
+ Number of non-simplicial facets: 8
-Statistics for: rbox 100 W1e-20 D6 t1327454215 | qhull Tv Qc
+Statistics for: rbox 100 W1e-20 D6 t1440987879 | qhull Tv Qc
Number of points processed: 100
- Number of hyperplanes created: 21073
- Number of distance tests for qhull: 33526
- Number of distance tests for merging: 178809
- Number of distance tests for checking: 119096
- Number of merged facets: 175
+ Number of hyperplanes created: 20966
+ Number of distance tests for qhull: 34320
+ Number of distance tests for merging: 192865
+ Number of distance tests for checking: 120654
+ Number of merged facets: 250
CPU seconds to compute hull (after input): 0.078
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 576900 distance computations.
+all facets. Will make 575600 distance computations.
rbox 50 W1e-20 D6 t | qhull Qv Tv Qc
Convex hull of 50 points in 6-d:
Number of vertices: 50
- Number of facets: 2052
- Number of non-simplicial facets: 1
+ Number of facets: 1963
+ Number of non-simplicial facets: 2
-Statistics for: rbox 50 W1e-20 D6 t1327454215 | qhull Qv Tv Qc
+Statistics for: rbox 50 W1e-20 D6 t1440987879 | qhull Qv Tv Qc
Number of points processed: 50
- Number of hyperplanes created: 6174
- Number of distance tests for qhull: 9126
- Number of distance tests for merging: 3342083
- Number of distance tests for checking: 42086
- Number of merged facets: 2
- CPU seconds to compute hull (after input): 0.125
+ Number of hyperplanes created: 6024
+ Number of distance tests for qhull: 8774
+ Number of distance tests for merging: 3163071
+ Number of distance tests for checking: 40164
+ Number of merged facets: 6
+ CPU seconds to compute hull (after input): 0.14
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 102600 distance computations.
+all facets. Will make 98150 distance computations.
rbox 10000 D4 t | qhull QR0 Qc C-0.01 A0.3 Tv
Convex hull of 10000 points in 4-d:
Number of vertices: 16
- Number of coplanar points: 8178
+ Number of coplanar points: 9157
Number of facets: 8
Number of non-simplicial facets: 8
-Statistics for: rbox 10000 D4 t1327454215 | qhull QR0 Qc C-0.01 A0.3 Tv QR1327454215
+Statistics for: rbox 10000 D4 t1440987879 | qhull QR0 Qc C-0.01 A0.3 Tv QR1440987879
- Number of points processed: 57
- Number of hyperplanes created: 390
- Number of distance tests for qhull: 1765089
- Number of distance tests for merging: 14211
- Number of distance tests for checking: 99978
- Number of merged facets: 419
- CPU seconds to compute hull (after input): 0.078
- Maximum distance of point above facet: 0.062
- Maximum distance of vertex below facet: -0.16
+ Number of points processed: 64
+ Number of hyperplanes created: 544
+ Number of distance tests for qhull: 2071618
+ Number of distance tests for merging: 17778
+ Number of distance tests for checking: 99566
+ Number of merged facets: 543
+ CPU seconds to compute hull (after input): 0.094
+ Maximum distance of point above facet: 0.045
+ Maximum distance of vertex below facet: -0.22 (0.1x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 80000 distance computations.
rbox 1000 D2 t | qhull d QR0 Qc C-1e-8 Qu Tv
Furthest-site Delaunay triangulation by the convex hull of 1000 points in 3-d:
Number of input sites: 1000
- Number of Delaunay regions: 16
+ Number of Delaunay regions: 13
-Statistics for: rbox 1000 D2 t1327454216 | qhull d QR0 Qc C-1e-8 Qu Tv QR1327454216
+Statistics for: rbox 1000 D2 t1440987879 | qhull d QR0 Qc C-1e-8 Qu Tv QR1440987879
Number of points processed: 1000
- Number of hyperplanes created: 5607
- Number of facets in hull: 1996
- Number of distance tests for qhull: 29361
- CPU seconds to compute hull (after input): 0
+ Number of hyperplanes created: 5497
+ Number of facets in hull: 1995
+ Number of distance tests for qhull: 30206
+ Number of distance tests for merging: 40979
+ Number of distance tests for checking: 25874
+ Number of merged facets: 2
+ CPU seconds to compute hull (after input): 0.015
+ Maximum distance of vertex below facet: -2.7e-009 (0.1x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 16000 distance computations.
+all facets. Will make 13000 distance computations.
rbox 300 D5 t |qhull A-0.999 Qx Qc Tcv
Convex hull of 300 points in 5-d:
Number of vertices: 151
- Number of coplanar points: 33
+ Number of coplanar points: 30
Number of facets: 1587
- Number of non-simplicial facets: 395
+ Number of non-simplicial facets: 406
-Statistics for: rbox 300 D5 t1327454216 | qhull A-0.999 Qx Qc Tcv
+Statistics for: rbox 300 D5 t1440987879 | qhull A-0.999 Qx Qc Tcv
- Number of points processed: 189
- Number of hyperplanes created: 11655
- Number of distance tests for qhull: 177205
- Number of distance tests for merging: 54298
- Number of distance tests for checking: 19295
- Number of merged facets: 1099
+ Number of points processed: 179
+ Number of hyperplanes created: 11581
+ Number of distance tests for qhull: 176487
+ Number of distance tests for merging: 53495
+ Number of distance tests for checking: 19366
+ Number of merged facets: 1059
CPU seconds to compute hull (after input): 0.046
- Maximum distance of vertex below facet: -0.026 (0.3x)
+ Maximum distance of vertex below facet: -0.021 (0.2x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
all facets. Will make 476100 distance computations.
rbox 100 D6 t |qhull A-0.9999 Qx Qc Tcv
Convex hull of 100 points in 6-d:
- Number of vertices: 84
+ Number of vertices: 90
Number of coplanar points: 1
- Number of facets: 3470
- Number of non-simplicial facets: 220
+ Number of facets: 3576
+ Number of non-simplicial facets: 209
-Statistics for: rbox 100 D6 t1327454216 | qhull A-0.9999 Qx Qc Tcv
+Statistics for: rbox 100 D6 t1440987879 | qhull A-0.9999 Qx Qc Tcv
- Number of points processed: 89
- Number of hyperplanes created: 13314
- Number of distance tests for qhull: 34056
- Number of distance tests for merging: 73326
- Number of distance tests for checking: 74943
- Number of merged facets: 516
- CPU seconds to compute hull (after input): 0.046
- Maximum distance of vertex below facet: -0.0066 (0.2x)
+ Number of points processed: 92
+ Number of hyperplanes created: 15254
+ Number of distance tests for qhull: 29366
+ Number of distance tests for merging: 76953
+ Number of distance tests for checking: 76495
+ Number of merged facets: 514
+ CPU seconds to compute hull (after input): 0.062
+ Maximum distance of vertex below facet: -0.0069 (0.2x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 347000 distance computations.
+all facets. Will make 357600 distance computations.
rbox 50 D7 t |qhull A-0.99999 Qx Qc Tcv W0.1
Convex hull of 50 points in 7-d:
- Number of vertices: 46
- Number of coplanar points: 2
- Number of facets: 5010
- Number of non-simplicial facets: 77
+ Number of vertices: 49
+ Number of facets: 5428
+ Number of non-simplicial facets: 98
-Statistics for: rbox 50 D7 t1327454216 | qhull A-0.99999 Qx Qc Tcv W0.1
+Statistics for: rbox 50 D7 t1440987880 | qhull A-0.99999 Qx Qc Tcv W0.1
- Number of points processed: 46
- Number of hyperplanes created: 14157
- Number of distance tests for qhull: 32822
- Number of distance tests for merging: 100043
- Number of distance tests for checking: 197564
- Number of merged facets: 230
+ Number of points processed: 49
+ Number of hyperplanes created: 14779
+ Number of distance tests for qhull: 19927
+ Number of distance tests for merging: 108508
+ Number of distance tests for checking: 99409
+ Number of merged facets: 282
CPU seconds to compute hull (after input): 0.078
- Maximum distance of point above facet: 0.23
- Maximum distance of vertex below facet: -0.0021 (0.2x)
+ Maximum distance of vertex below facet: -0.0019 (0.2x)
QH7076 qhull input warning: exact merge ('Qx'). Verify may report that a point
is outside of a facet. See qh-optq.htm#Qx
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 250500 distance computations.
+all facets. Will make 271400 distance computations.
echo === check bad cases for Qhull. May cause errors ${d:-`date`}
date
-=== check bad cases for Qhull. May cause errors Tue Jan 24 20:16:56 EST 2012
+=== check bad cases for Qhull. May cause errors Sun Aug 30 22:24:40 EDT 2015
rbox 1000 L100000 s G1e-6 t | qhull Tv
Convex hull of 1000 points in 3-d:
- Number of vertices: 996
- Number of facets: 1524
+ Number of vertices: 991
+ Number of facets: 1483
Number of non-simplicial facets: 4
-Statistics for: rbox 1000 L100000 s G1e-6 t1327454216 | qhull Tv
+Statistics for: rbox 1000 L100000 s G1e-6 t1440987880 | qhull Tv
- Number of points processed: 996
- Number of hyperplanes created: 3709
- Number of distance tests for qhull: 28946
- Number of distance tests for merging: 132465
- Number of distance tests for checking: 118998
- Number of merged facets: 465
- CPU seconds to compute hull (after input): 0.015
- Maximum distance of point above facet: 1.8e-015 (0.3x)
+ Number of points processed: 992
+ Number of hyperplanes created: 3539
+ Number of distance tests for qhull: 30572
+ Number of distance tests for merging: 146807
+ Number of distance tests for checking: 134285
+ Number of merged facets: 496
+ CPU seconds to compute hull (after input): 0.016
+ Maximum distance of vertex below facet: -1.7e-015 (0.3x)
qhull precision warning:
The initial hull is narrow (cosine of min. angle is 1.0000000000000000).
Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may
produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale
last coordinate) may remove this warning. Use 'Pp' to skip this warning.
See 'Limitations' in qh-impre.htm.
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 1524000 distance computations.
+all facets. Will make 1483000 distance computations.
rbox 1000 L100000 s G1e-6 t | qhull Tv Q10
Convex hull of 1000 points in 3-d:
- Number of vertices: 996
- Number of facets: 1524
+ Number of vertices: 991
+ Number of facets: 1483
Number of non-simplicial facets: 4
-Statistics for: rbox 1000 L100000 s G1e-6 t1327454216 | qhull Tv Q10
+Statistics for: rbox 1000 L100000 s G1e-6 t1440987880 | qhull Tv Q10
- Number of points processed: 996
- Number of hyperplanes created: 3709
- Number of distance tests for qhull: 28942
- Number of distance tests for merging: 132465
- Number of distance tests for checking: 118998
- Number of merged facets: 465
- CPU seconds to compute hull (after input): 0.031
- Maximum distance of point above facet: 1.8e-015 (0.3x)
+ Number of points processed: 992
+ Number of hyperplanes created: 3539
+ Number of distance tests for qhull: 30569
+ Number of distance tests for merging: 146807
+ Number of distance tests for checking: 134285
+ Number of merged facets: 496
+ CPU seconds to compute hull (after input): 0.016
+ Maximum distance of vertex below facet: -1.7e-015 (0.3x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 1524000 distance computations.
+all facets. Will make 1483000 distance computations.
rbox 1000 s Z1 G1e-13 t | qhull Tv
Convex hull of 1001 points in 3-d:
Number of vertices: 1001
- Number of facets: 1490
- Number of non-simplicial facets: 165
+ Number of facets: 1402
+ Number of non-simplicial facets: 107
-Statistics for: rbox 1000 s Z1 G1e-13 t1327454216 | qhull Tv
+Statistics for: rbox 1000 s Z1 G1e-13 t1440987880 | qhull Tv
Number of points processed: 1001
- Number of hyperplanes created: 4496
- Number of distance tests for qhull: 29800
- Number of distance tests for merging: 77271
- Number of distance tests for checking: 185199
- Number of merged facets: 1602
- CPU seconds to compute hull (after input): 0.015
- Maximum distance of point above facet: 8.9e-015 (1.6x)
- Maximum distance of vertex below facet: -9.1e-015 (1.6x)
+ Number of hyperplanes created: 4961
+ Number of distance tests for qhull: 29235
+ Number of distance tests for merging: 194544
+ Number of distance tests for checking: 421790
+ Number of merged facets: 2264
+ CPU seconds to compute hull (after input): 0.046
+ Maximum distance of point above facet: 1.9e-014 (3.5x)
+ Maximum distance of vertex below facet: -1.8e-014 (3.2x)
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 1491490 distance computations.
+all facets. Will make 1403402 distance computations.
rbox 1000 s W1e-13 P0 t | qhull d Qbb Qc Tv
Delaunay triangulation by the convex hull of 1001 points in 4-d:
Number of input sites: 1001
Number of Delaunay regions: 1996
-Statistics for: rbox 1000 s W1e-13 P0 t1327454216 | qhull d Qbb Qc Tv
+Statistics for: rbox 1000 s W1e-13 P0 t1440987880 | qhull d Qbb Qc Tv
Number of points processed: 1001
- Number of hyperplanes created: 133732
- Number of facets in hull: 2018
- Number of distance tests for qhull: 210877
- Number of distance tests for merging: 9912396
- Number of distance tests for checking: 2007669
- Number of merged facets: 127605
- CPU seconds to compute hull (after input): 2.562
- Maximum distance of point above facet: 2.7e-012 (136.2x)
- Maximum distance of vertex below facet: -8e-013 (39.9x)
+ Number of hyperplanes created: 15056
+ Number of facets in hull: 3672
+ Number of distance tests for qhull: 63181
+ Number of distance tests for merging: 255225
+ Number of distance tests for checking: 331691
+ Number of merged facets: 5938
+ CPU seconds to compute hull (after input): 0.078
+ Maximum distance of point above facet: 1.5e-013 (7.5x)
+ Maximum distance of vertex below facet: -1.6e-013 (7.7x)
Output completed. Verifying that all points are below outer planes of
all facets. Will make 1997996 distance computations.
rbox 1000 s W1e-13 t | qhull d Tv
Delaunay triangulation by the convex hull of 1000 points in 4-d:
- Number of input sites: 37
- Total number of deleted points due to merging: 316
- Total number of nearly incident points: 647
- Number of Delaunay regions: 30
- Number of non-simplicial Delaunay regions: 10
-
-Statistics for: rbox 1000 s W1e-13 t1327454219 | qhull d Tv
-
- Number of points processed: 353
- Number of hyperplanes created: 4824
- Number of facets in hull: 53
- Number of distance tests for qhull: 956652
- Number of distance tests for merging: 160982
- Number of distance tests for checking: 50330
- Number of merged facets: 4255
- CPU seconds to compute hull (after input): 0.063
- Maximum distance of point above facet: 3.4e-013 (33.8x)
- Maximum distance of vertex below facet: -4.7e-014 (4.7x)
+ Number of input sites: 949
+ Total number of deleted points due to merging: 17
+ Total number of nearly incident points: 34
+ Number of Delaunay regions: 1162
+ Number of non-simplicial Delaunay regions: 408
+
+Statistics for: rbox 1000 s W1e-13 t1440987880 | qhull d Tv
+
+ Number of points processed: 966
+ Number of hyperplanes created: 10945
+ Number of facets in hull: 2391
+ Number of distance tests for qhull: 1000255
+ Number of distance tests for merging: 271458
+ Number of distance tests for checking: 1760648
+ Number of merged facets: 7286
+ CPU seconds to compute hull (after input): 0.187
+ Maximum distance of point above facet: 1.5e-012 (150.2x)
+ Maximum distance of vertex below facet: -4.9e-014 (4.9x)
qhull precision warning:
The initial hull is narrow (cosine of min. angle is 1.0000000000000000).
Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may
produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale
last coordinate) may remove this warning. Use 'Pp' to skip this warning.
See 'Limitations' in qh-impre.htm.
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 30000 distance computations.
+all facets. Will make 1162000 distance computations.
rbox 1000 s W1e-13 t D2 | qhull d Tv
Delaunay triangulation by the convex hull of 1000 points in 3-d:
Number of input sites: 974
- Total number of deleted points due to merging: 10
- Total number of nearly incident points: 16
- Number of Delaunay regions: 729
- Number of non-simplicial Delaunay regions: 132
-
-Statistics for: rbox 1000 s W1e-13 D2 t1327454219 | qhull d Tv
-
- Number of points processed: 984
- Number of hyperplanes created: 3940
- Number of facets in hull: 1462
- Number of distance tests for qhull: 68482
- Number of distance tests for merging: 47115
- Number of distance tests for checking: 167978
- Number of merged facets: 885
- CPU seconds to compute hull (after input): 0.016
- Maximum distance of point above facet: 3e-014 (5.5x)
- Maximum distance of vertex below facet: -7.6e-015 (1.4x)
+ Total number of deleted points due to merging: 8
+ Total number of nearly incident points: 18
+ Number of Delaunay regions: 731
+ Number of non-simplicial Delaunay regions: 140
+
+Statistics for: rbox 1000 s W1e-13 D2 t1440987881 | qhull d Tv
+
+ Number of points processed: 982
+ Number of hyperplanes created: 3775
+ Number of facets in hull: 1445
+ Number of distance tests for qhull: 143137
+ Number of distance tests for merging: 42627
+ Number of distance tests for checking: 495000
+ Number of merged facets: 821
+ CPU seconds to compute hull (after input): 0.031
+ Maximum distance of point above facet: 3.5e-013 (62.7x)
+ Maximum distance of vertex below facet: -7.3e-015 (1.3x)
qhull precision warning:
The initial hull is narrow (cosine of min. angle is 1.0000000000000000).
Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may
produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale
last coordinate) may remove this warning. Use 'Pp' to skip this warning.
See 'Limitations' in qh-impre.htm.
Output completed. Verifying that all points are below outer planes of
-all facets. Will make 729000 distance computations.
+all facets. Will make 731000 distance computations.
echo =======================================================
=======================================================
echo =======================================================
=======================================================
echo === The following commands may cause errors ${d:-`date`}
date
-=== The following commands may cause errors Tue Jan 24 20:16:59 EST 2012
+=== The following commands may cause errors Sun Aug 30 22:24:41 EDT 2015
echo =======================================================
=======================================================
echo =======================================================
=======================================================
rbox c D7 | qhull Q0 Tcv
Convex hull of 128 points in 7-d:
Number of vertices: 128
Number of facets: 8666
Statistics for: rbox c D7 | qhull Q0 Tcv
Number of points processed: 128
Number of hyperplanes created: 12287
Number of distance tests for qhull: 32936
CPU seconds to compute hull (after input): 0.031
precision problems (corrected unless 'Q0' or an error)
41888 coplanar half ridges in output
10185 coplanar horizon facets for new vertices
8389 nearly singular or axis-parallel hyperplanes
8389 zero divisors during back substitute
11903 zero divisors during gaussian elimination
qhull output completed. Verifying that 128 points are
below 6.6e-015 of the nearest facet.
rbox 100 s D3 | qhull Q0 E1e-3 Tc Po
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 s D3 | qhull Q0 E1e-3 Tc Po
Number of points processed: 100
Number of hyperplanes created: 508
Number of distance tests for qhull: 1728
CPU seconds to compute hull (after input): 0
QH6115 qhull precision error: f100 is concave to f247, since p44(v13) is 0.002232 above
QH6115 qhull precision error: f139 is concave to f274, since p90(v32) is 0.007128 above
QH6115 qhull precision error: f163 is concave to f232, since p5(v6) is 0.001226 above
QH6115 qhull precision error: f293 is concave to f389, since p11(v61) is 0.002161 above
QH6115 qhull precision error: f307 is concave to f459, since p75(v21) is 0.01537 above
precision problems (corrected unless 'Q0' or an error)
16 coplanar half ridges in output
5 concave half ridges in output
18 coplanar horizon facets for new vertices
rbox 100 s D3 | qhull Q0 E1e-2 Tc Po
Convex hull of 100 points in 3-d:
Number of vertices: 72
Number of facets: 140
Statistics for: rbox 100 s D3 | qhull Q0 E1e-2 Tc Po
Number of points processed: 72
Number of hyperplanes created: 321
Number of distance tests for qhull: 1693
CPU seconds to compute hull (after input): 0
QH6115 qhull precision error: f123 is concave to f235, since p85(v8) is 0.06092 above
QH6115 qhull precision error: f177 is concave to f272, since p98(v20) is 0.03571 above
QH6115 qhull precision error: f246 is concave to f252, since p7(v57) is 0.02104 above
QH6115 qhull precision error: f261 is concave to f305, since p82(v60) is 0.01847 above
QH6115 qhull precision error: f266 is concave to f317, since p82(v60) is 0.02592 above
precision problems (corrected unless 'Q0' or an error)
52 coplanar half ridges in output
5 concave half ridges in output
54 coplanar horizon facets for new vertices
27 coplanar points during partitioning
rbox 100 s D3 | qhull Q0 E1e-1 Tc Po
Convex hull of 100 points in 3-d:
Number of vertices: 10
Number of facets: 16
Statistics for: rbox 100 s D3 | qhull Q0 E1e-1 Tc Po
Number of points processed: 10
Number of hyperplanes created: 27
Number of distance tests for qhull: 977
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
3 coplanar half ridges in output
3 coplanar horizon facets for new vertices
59 coplanar points during partitioning
rbox 100 s D3 | qhull Q0 R1e-3 Tc Po
Convex hull of 100 points in 3-d:
Number of vertices: 100
Number of facets: 196
Statistics for: rbox 100 s D3 | qhull Q0 R1e-3 Tc Po
Number of points processed: 100
Number of hyperplanes created: 513
Number of distance tests for qhull: 1693
CPU seconds to compute hull (after input): 0
QH6115 qhull precision error: f229 is concave to f300, since p90(v34) is 0.007895 above
QH6115 qhull precision error: f323 is concave to f421, since p11(v67) is 0.001894 above
QH6115 qhull precision error: f343 is concave to f493, since p75(v21) is 0.011 above
QH6115 qhull precision error: f493 is concave to f343, since p25(v97) is 0.000937 above
precision problems (corrected unless 'Q0' or an error)
14 coplanar half ridges in output
4 concave half ridges in output
9 coplanar horizon facets for new vertices
rbox 100 s D3 | qhull Q0 R1e-2 Tc Po
Convex hull of 100 points in 3-d:
Number of vertices: 87
Number of facets: 170
Statistics for: rbox 100 s D3 | qhull Q0 R1e-2 Tc Po
Number of points processed: 87
Number of hyperplanes created: 405
Number of distance tests for qhull: 1734
- CPU seconds to compute hull (after input): 0.015
+ CPU seconds to compute hull (after input): 0
QH6136 qhull precision error: facet f326 is flipped, distance= 0.51437088552
QH6136 qhull precision error: facet f326 is flipped, distance= 0.511098236347
QH6115 qhull precision error: f76 is concave to f201, since p76(v21) is 0.0101 above
QH6115 qhull precision error: f96 is concave to f279, since p38(v22) is 0.008383 above
QH6115 qhull precision error: f132 is concave to f140, since p57(v0) is 0.02117 above
QH6115 qhull precision error: f140 is concave to f132, since p96(v34) is 0.00703 above
QH6115 qhull precision error: f150 is concave to f230, since p11(v37) is 0.04121 above
QH6115 qhull precision error: f161 is concave to f326, since p26(v32) is 0.01279 above
QH6115 qhull precision error: f194 is concave to f281, since p73(v12) is 0.03149 above
QH6115 qhull precision error: f230 is concave to f150, since p47(v52) is 0.008464 above
QH6115 qhull precision error: f263 is concave to f156, since p15(v60) is 0.01055 above
QH6115 qhull precision error: f277 is concave to f353, since p89(v36) is 0.005387 above
QH6115 qhull precision error: f281 is concave to f194, since p66(v63) is 0.005996 above
QH6115 qhull precision error: f319 is concave to f341, since p82(v70) is 0.07818 above
QH6115 qhull precision error: f324 is concave to f368, since p41(v5) is 0.01436 above
QH6113 qhull precision error: f326 is flipped(interior point is outside)
QH6115 qhull precision error: f344 is concave to f352, since p29(v75) is 0.009226 above
QH6115 qhull precision error: f348 is concave to f351, since p27(v76) is 0.008815 above
QH6115 qhull precision error: f349 is concave to f350, since p15(v60) is 0.01089 above
QH6115 qhull precision error: f352 is concave to f344, since p69(v77) is 0.008279 above
QH6115 qhull precision error: f353 is concave to f277, since p69(v77) is 0.006627 above
QH6115 qhull precision error: f385 is concave to f404, since p18(v73) is 0.007494 above
QH6115 qhull precision error: f404 is concave to f385, since p13(v87) is 0.005049 above
precision problems (corrected unless 'Q0' or an error)
45 coplanar half ridges in output
20 concave half ridges in output
1 flipped facets
47 coplanar horizon facets for new vertices
13 coplanar points during partitioning
rbox 100 s D3 | qhull Q0 R0.05 Tc
QH6136 qhull precision error: facet f160 is flipped, distance= 0.41168102504
ERRONEOUS FACET:
- f160
- flags: bottom simplicial flipped
- normal: -0.3615 -0.1924 0.9123
- offset: 0.4644952
- vertices: p94(v40) p19(v28) p56(v27)
- neighboring facets: f107 f158 f202
QH6136 qhull precision error: facet f203 is flipped, distance= 0.448767103644
ERRONEOUS FACET:
- f203
- flags: top simplicial flipped
- normal: -0.2281 0.05702 -0.972
- offset: 0.4136177
- vertices: p40(v51) p83(v19) p48(v6)
- neighboring facets: f123 f204 f205
A flipped facet occurs when its distance to the interior point is
greater than -0.024, the maximum roundoff error.
While executing: rbox 100 s D3 | qhull Q0 R0.05 Tc
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315466858 Q0-no-premerge Random_perturb 0.05 Tcheck-frequently
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510228748 Q0-no-premerge Random_perturb 0.05 Tcheck-frequently
_max-width 0.94 Error-roundoff 0.024 Visible-distance 0.024
U-coplanar-distance 0.024 Width-outside 0.048 _wide-facet 0.15
Last point added to hull was p40.
Qhull has finished constructing the hull.
At error exit:
Convex hull of 100 points in 3-d:
Number of vertices: 51
Number of facets: 98
Statistics for: rbox 100 s D3 | qhull Q0 R0.05 Tc
Number of points processed: 51
Number of hyperplanes created: 206
Number of distance tests for qhull: 2041
CPU seconds to compute hull (after input): 0
precision problems (corrected unless 'Q0' or an error)
- 2 flipped facets
50 coplanar horizon facets for new vertices
- 46 coplanar points during partitioning
Precision problems were detected during construction of the convex hull.
This occurs because convex hull algorithms assume that calculations are
exact, but floating-point arithmetic has roundoff errors.
To correct for precision problems, do not use 'Q0'. By default, Qhull
selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',
Qhull joggles the input to prevent precision problems. See "Imprecision
in Qhull" (qh-impre.htm).
If you use 'Q0', the output may include
coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,
Qhull may produce a ridge with four neighbors or two facets with the same
vertices. Qhull reports these events when they occur. It stops when a
concave ridge, flipped facet, or duplicate facet occurs.
If you need triangular output:
- use option 'Qt' to triangulate the output
- use option 'QJ' to joggle the input points and remove precision errors
- use option 'Ft'. It triangulates non-simplicial facets with added points.
If you must use 'Q0',
try one or more of the following options. They can not guarantee an output.
- use 'QbB' to scale the input to a cube.
- use 'Po' to produce output and prevent partitioning for flipped facets
- use 'V0' to set min. distance to visible facet as 0 instead of roundoff
- use 'En' to specify a maximum roundoff error less than 0.024.
- options 'Qf', 'Qbb', and 'QR0' may also help
To guarantee simplicial output:
- use option 'Qt' to triangulate the output
- use option 'QJ' to joggle the input points and remove precision errors
- use option 'Ft' to triangulate the output by adding points
- use exact arithmetic (see "Imprecision in Qhull", qh-impre.htm)
rbox 100 s D3 | qhull Q0 R0.05 Tc Po
Convex hull of 100 points in 3-d:
Number of vertices: 51
Number of facets: 98
Statistics for: rbox 100 s D3 | qhull Q0 R0.05 Tc Po
Number of points processed: 51
Number of hyperplanes created: 209
Number of distance tests for qhull: 2072
CPU seconds to compute hull (after input): 0
QH6136 qhull precision error: facet f105 is flipped, distance= 0.531034433025
QH6136 qhull precision error: facet f172 is flipped, distance= 0.351989788321
QH6136 qhull precision error: facet f105 is flipped, distance= 0.524438872687
QH6136 qhull precision error: facet f172 is flipped, distance= 0.311891927779
QH6115 qhull precision error: f30 is concave to f172, since p90(v11) is 0.05852 above
QH6115 qhull precision error: f41 is concave to f70, since p28(v14) is 0.03835 above
QH6115 qhull precision error: f65 is concave to f128, since p18(v19) is 0.03961 above
QH6115 qhull precision error: f77 is concave to f201, since p89(v21) is 0.03681 above
QH6115 qhull precision error: f99 is concave to f192, since p85(v8) is 0.1891 above
QH6113 qhull precision error: f105 is flipped(interior point is outside)
QH6115 qhull precision error: f143 is concave to f179, since p3(v2) is 0.0956 above
QH6115 qhull precision error: f150 is concave to f185, since p70(v13) is 0.03157 above
QH6115 qhull precision error: f161 is concave to f171, since p41(v5) is 0.07964 above
QH6115 qhull precision error: f166 is concave to f108, since p96(v41) is 0.02537 above
QH6115 qhull precision error: f169 is concave to f129, since p60(v42) is 0.02492 above
QH6113 qhull precision error: f172 is flipped(interior point is outside)
QH6115 qhull precision error: f183 is concave to f205, since p44(v37) is 0.1309 above
QH6115 qhull precision error: f186 is concave to f207, since p5(v25) is 0.1066 above
QH6115 qhull precision error: f187 is concave to f151, since p75(v47) is 0.04347 above
QH6115 qhull precision error: f199 is concave to f200, since p12(v3) is 0.08495 above
QH6115 qhull precision error: f201 is concave to f77, since p35(v50) is 0.02603 above
precision problems (corrected unless 'Q0' or an error)
61 coplanar half ridges in output
15 concave half ridges in output
2 flipped facets
44 coplanar horizon facets for new vertices
46 coplanar points during partitioning
rbox 1000 W1e-7 | qhull Q0 Tc Po
Convex hull of 1000 points in 3-d:
Number of vertices: 164
Number of facets: 324
Statistics for: rbox 1000 W1e-7 | qhull Q0 Tc Po
Number of points processed: 221
Number of hyperplanes created: 1160
Number of distance tests for qhull: 22647
CPU seconds to compute hull (after input): 0
rbox 50 s | qhull Q0 V0.05 W0.01 Tc Po
QH6136 qhull precision error: facet f105 is flipped, distance= 0.328228630954
QH6136 qhull precision error: facet f125 is flipped, distance= 0.389476173148
QH6136 qhull precision error: facet f152 is flipped, distance= 0.420187947128
QH6136 qhull precision error: facet f155 is flipped, distance= 0.396217639489
QH6136 qhull precision error: facet f161 is flipped, distance= 0.0543980568868
QH6136 qhull precision error: facet f164 is flipped, distance= 0.448464152152
QH6136 qhull precision error: facet f170 is flipped, distance= 0.430073300444
QH6136 qhull precision error: facet f105 is flipped, distance= 0.328228630954
QH6136 qhull precision error: facet f125 is flipped, distance= 0.389476173148
QH6136 qhull precision error: facet f152 is flipped, distance= 0.420187947128
QH6136 qhull precision error: facet f155 is flipped, distance= 0.396217639489
QH6136 qhull precision error: facet f161 is flipped, distance= 0.0543980568868
QH6136 qhull precision error: facet f164 is flipped, distance= 0.448464152152
QH6136 qhull precision error: facet f170 is flipped, distance= 0.430073300444
QH6115 qhull precision error: f25 is concave to f60, since p41(v8) is 0.1672 above
QH6115 qhull precision error: f25 is concave to f155, since p19(v2) is 0.01771 above
QH6115 qhull precision error: f38 is concave to f70, since p0(v13) is 0.06094 above
QH6115 qhull precision error: f39 is concave to f145, since p8(v11) is 0.2589 above
QH6115 qhull precision error: f45 is concave to f72, since p5(v15) is 0.02091 above
QH6115 qhull precision error: f47 is concave to f98, since p5(v15) is 0.05573 above
QH6115 qhull precision error: f47 is concave to f96, since p42(v7) is 0.05284 above
QH6115 qhull precision error: f50 is concave to f59, since p49(v16) is 0.01059 above
QH6115 qhull precision error: f54 is concave to f84, since p28(v17) is 0.03013 above
QH6115 qhull precision error: f54 is concave to f152, since p29(v1) is 0.2143 above
QH6115 qhull precision error: f59 is concave to f50, since p1(v19) is 0.01736 above
QH6115 qhull precision error: f60 is concave to f25, since p1(v19) is 0.02263 above
QH6115 qhull precision error: f62 is concave to f119, since p14(v5) is 0.02783 above
QH6115 qhull precision error: f65 is concave to f120, since p16(v10) is 0.003387 above
QH6115 qhull precision error: f70 is concave to f38, since p9(v22) is 0.04722 above
QH6115 qhull precision error: f71 is concave to f73, since p9(v22) is 0.04568 above
QH6115 qhull precision error: f72 is concave to f45, since p31(v23) is 0.02334 above
QH6115 qhull precision error: f73 is concave to f71, since p31(v23) is 0.04141 above
QH6115 qhull precision error: f78 is concave to f125, since p38(v24) is 0.01386 above
QH6115 qhull precision error: f84 is concave to f54, since p25(v26) is 0.01696 above
QH6115 qhull precision error: f87 is concave to f93, since p14(v5) is 0.01836 above
QH6115 qhull precision error: f88 is concave to f112, since p4(v27) is 0.04742 above
QH6115 qhull precision error: f91 is concave to f161, since p26(v28) is 0.3121 above
QH6115 qhull precision error: f93 is concave to f87, since p26(v28) is 0.01572 above
QH6115 qhull precision error: f96 is concave to f47, since p21(v29) is 0.02763 above
QH6115 qhull precision error: f98 is concave to f47, since p20(v30) is 0.03086 above
QH6113 qhull precision error: f105 is flipped(interior point is outside)
QH6115 qhull precision error: f106 is concave to f149, since p29(v1) is 0.0618 above
QH6115 qhull precision error: f112 is concave to f88, since p6(v34) is 0.02917 above
QH6115 qhull precision error: f119 is concave to f62, since p39(v36) is 0.006072 above
QH6115 qhull precision error: f120 is concave to f65, since p39(v36) is 0.001213 above
QH6113 qhull precision error: f125 is flipped(interior point is outside)
QH6115 qhull precision error: f134 is concave to f139, since p46(v40) is 0.07699 above
QH6115 qhull precision error: f139 is concave to f134, since p47(v41) is 0.01871 above
QH6115 qhull precision error: f141 is concave to f144, since p47(v41) is 0.1017 above
QH6115 qhull precision error: f144 is concave to f14
Convex hull of 50 points in 3-d:
Number of vertices: 50
Number of facets: 96
Statistics for: rbox 50 s | qhull Q0 V0.05 W0.01 Tc Po
Number of points processed: 50
Number of hyperplanes created: 171
Number of distance tests for qhull: 552
CPU seconds to compute hull (after input): 0
1, since p35(v42) is 0.03263 above
QH6115 qhull precision error: f145 is concave to f39, since p2(v43) is 0.04048 above
QH6115 qhull precision error: f149 is concave to f106, since p18(v44) is 0.009672 above
QH6113 qhull precision error: f152 is flipped(interior point is outside)
QH6113 qhull precision error: f155 is flipped(interior point is outside)
QH6113 qhull precision error: f161 is flipped(interior point is outside)
QH6113 qhull precision error: f164 is flipped(interior point is outside)
QH6115 qhull precision error: f166 is concave to f170, since p16(v10) is 0.04552 above
QH6113 qhull precision error: f170 is flipped(interior point is outside)
precision problems (corrected unless 'Q0' or an error)
37 concave half ridges in output
7 flipped facets
82 coplanar horizon facets for new vertices
rbox 100 s D5 | qhull Q0 R1e-2 Tc Po
Convex hull of 100 points in 5-d:
Number of vertices: 37
Number of facets: 500
Statistics for: rbox 100 s D5 | qhull Q0 R1e-2 Tc Po
Number of points processed: 37
Number of hyperplanes created: 1198
Number of distance tests for qhull: 2764
QH6107 qhull precision error: facets f1150, f1191 and f1152 meet at a ridge with more than 2 neighbors. Can not continue.
ERRONEOUS FACET:
- f1150
- flags: top simplicial new
- normal: -0.7563 0.3207 -0.3738 0.2956 0.3133
- offset: -0.2362615
- vertices: p70(v37) p59(v25) p47(v17) p33(v15) p6(v9)
- neighboring facets: f519 f1148 f1151 f1152 f1153
ERRONEOUS OTHER FACET:
- f1191
- flags: top simplicial new
- normal: 0.7615 -0.2592 0.3014 -0.3662 -0.3577
- offset: 0.27682
- vertices: p70(v37) p59(v25) p47(v17) p6(v9) p54(v0)
- neighboring facets: f519 f1148
ERRONEOUS and NEIGHBORING FACETS to output
While executing: rbox 100 s D5 | qhull Q0 R1e-2 Tc Po
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 315466858 Q0-no-premerge Random_perturb 0.01 Tcheck-frequently
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1510228748 Q0-no-premerge Random_perturb 0.01 Tcheck-frequently
Poutput-forced _max-width 0.88 Error-roundoff 0.0045
Visible-distance 0.0045 U-coplanar-distance 0.0045 Width-outside 0.009
_wide-facet 0.027
Last point added to hull was p70.
precision problems (corrected unless 'Q0' or an error)
50 coplanar horizon facets for new vertices
Precision problems were detected during construction of the convex hull.
This occurs because convex hull algorithms assume that calculations are
exact, but floating-point arithmetic has roundoff errors.
To correct for precision problems, do not use 'Q0'. By default, Qhull
selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',
Qhull joggles the input to prevent precision problems. See "Imprecision
in Qhull" (qh-impre.htm).
If you use 'Q0', the output may include
coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,
Qhull may produce a ridge with four neighbors or two facets with the same
vertices. Qhull reports these events when they occur. It stops when a
concave ridge, flipped facet, or duplicate facet occurs.
If you need triangular output:
- use option 'Qt' to triangulate the output
- use option 'QJ' to joggle the input points and remove precision errors
- use option 'Ft'. It triangulates non-simplicial facets with added points.
If you must use 'Q0',
try one or more of the following options. They can not guarantee an output.
- use 'QbB' to scale the input to a cube.
- use 'Po' to produce output and prevent partitioning for flipped facets
- use 'V0' to set min. distance to visible facet as 0 instead of roundoff
- use 'En' to specify a maximum roundoff error less than 0.0045.
- options 'Qf', 'Qbb', and 'QR0' may also help
To guarantee simplicial output:
- use option 'Qt' to triangulate the output
- use option 'QJ' to joggle the input points and remove precision errors
- use option 'Ft' to triangulate the output by adding points
- use exact arithmetic (see "Imprecision in Qhull", qh-impre.htm)
qhull
-qhull- compute convex hulls and related structures. Qhull 2012.1 2012/01/22
+qhull- compute convex hulls and related structures. Qhull 2015.0.2.r 2015/08/30
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 - joggled input instead of merged facets
Tv - verify result: structure, convexity, and point inclusion
. - concise list of all options
- - one-line description of each option
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 D4 | qhull Tv 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 c d D2 | qhull Qc s f Fx | more 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
+ rbox y 1000 W0 | qhull rbox c | qhull n
qhull .
-Qhull 2012.1 2012/01/22.
+Qhull 2015.0.2.r 2015/08/30.
Except for 'F.' and 'PG', upper-case options take an argument.
delaunay voronoi Geomview Halfspace facet_dump
incidences mathematica normals OFF_format points
summary
Farea FArea-total Fcoplanars FCentrums Fd-cdd-in
FD-cdd-out FF-dump-xridge Finner FIDs Fmerges
Fneighbors FNeigh-vertex Fouter FOptions Fpoint-intersect
FPoint_near FQhull Fsummary FSize Ftriangles
Fvertices Fvoronoi FVertex-ave Fxtremes FMaple
Gvertices Gpoints Gall_points Gno_planes Ginner
Gcentrums Ghyperplanes Gridges Gouter GDrop_dim
Gtransparent
PArea-keep Pdrop d0:0D0 Pgood PFacet_area_keep
PGood_neighbors PMerge-keep Poutput_forced Pprecision_not
QbBound 0:0.5 Qbk:0Bk:0_drop QbB-scale-box Qbb-scale-last Qcoplanar
Qfurthest Qgood_only QGood_point Qinterior Qmax_out
QJoggle Qrandom QRotate Qsearch_1st Qtriangulate
QupperDelaunay QVertex_good Qvneighbors Qxact_merge Qzinfinite
Q0_no_premerge Q1_no_angle Q2_no_independ Q3_no_redundant Q4_no_old
Q5_no_check_out Q6_no_concave Q7_depth_first Q8_no_near_in Q9_pick_furthest
Q10_no_narrow Q11_trinormals
T4_trace Tannotate Tcheck_often Tstatistics Tverify
Tz_stdout TFacet_log TInput_file TPoint_trace TMerge_trace
TOutput_file TRerun TWide_trace TVertex_stop TCone_stop
Angle_max Centrum_size Error_round Random_dist Visible_min
Ucoplanar_max Wide_outside
qhull -
qhull- compute convex hulls and related structures.
- http://www.qhull.org 2012.1 2012/01/22
+ http://www.qhull.org 2015.0.2.r 2015/08/30
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 preceeded 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 - joggled input instead of merged 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 angle-coplanar 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 premerge 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
Topts- Trace options:
T4 - trace at level n, 4=all, 5=mem/gauss, -1= events
Ta - annotate output with message codes
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
rbox
-rbox- generate various point distributions. Default is random in cube.
-args (any order, space separated): Version: 2001/06/24
+args (any order, space separated): Version: 2015/08/30
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
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+006
cat html/qhull.txt html/rbox.txt
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: <http://www.qhull.org>
- GIT: <git@gitorious.org:qhull/qhull.git>
- mirror: <http://www6.uniovi.es/ftp/pub/mirrors/geom.umn.edu/software/ghindex.html>
- news: <http://www.qhull.org/news>
- Geomview: <http://www.geomview.org>
- news group: <news:comp.graphics.algorithms>
- FAQ: <http://exaflop.org/docs/cgafaq/cga6.html>
- 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= <<
<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]]".
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.
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
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
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
# end of q_test
diff --git a/eg/qhull-zip.sh b/eg/qhull-zip.sh
index b9b04b5..1109994 100644
--- a/eg/qhull-zip.sh
+++ b/eg/qhull-zip.sh
@@ -1,257 +1,260 @@
#!/bin/sh
#
# qhull-zip.sh version -- Make zip and tgz files for Qhull release
#
# wzzip from http://www.winzip.com/wzcline.htm
# can not use path with $zip_file
# odd error messages if can't locate directory
#
-# $Id: //main/2011/qhull/eg/qhull-zip.sh#16 $$Change: 1493 $
-# $DateTime: 2012/02/20 09:31:24 $$Author: bbarber $
+# $Id: //main/2011/qhull/eg/qhull-zip.sh#23 $$Change: 1954 $
+# $DateTime: 2015/08/30 22:57:35 $$Author: bbarber $
if [[ $# -eq 0 ]]; then
echo 'Missing date stamp, e.g., qhull-zip.sh 2007.1'
exit
fi
version=$1
err_program=qhull-zip
err_log=/var/tmp/qhull-zip.log
[[ -e $HOME/bash/etc/road-script.sh ]] && source $HOME/bash/etc/road-script.sh \
|| source /etc/road-script.sh
check_err_log $LINENO "$err_log"
check_err_log $LINENO "$err_step_log"
log_step $LINENO "Logging to $err_log\n... and $err_step_log"
log_note $LINENO "Find Qhull directory"
if [[ ! -d qhull/eg && ! -d ../qhull/eg && -d ../../qhull/eg ]]; then
exit_err $LINENO "qhull/eg directory not found at or above $PWD"
fi
if [[ ! -d qhull/eg ]]; then
if [[ -d ../qhull/eg ]]; then
cd ..
else
cd ../.. # Tested above
fi
fi
root_dir=$(pwd)
TEMP_DIR="$TMP/qhull-zip-$(ro_today2)"
TEMP_FILE="$TMP/qhull-zip-$(ro_today2).txt"
qhull_zip_file=qhull-$version.zip # no path or spaces
qhull_tgz_file=qhull-$version-src.tgz
qhullmd5_file=qhull-$version.md5sum
exit_if_fail $LINENO "rm -f $qhull_zip_file $qhull_tgz_file $qhullmd5_file"
#############################
log_step $LINENO "Check environment"
#############################
[[ $(type -p md5sum) ]] || exit_err $LINENO "md5sum is missing"
[[ $(cp --help || grep '[-]-parents') ]] || exit_err $LINENO "cp does not have --parents option"
#############################
log_step $LINENO "Define functions"
#############################
function check_zip_file #zip_file
{
local zip_file=$1
local HERE=$(ro_here)
log_note $HERE "Check $zip_file"
ls -l $zip_file >>$err_log
exit_if_err $HERE "Did not create $zip_file"
wzunzip -ybc -t $zip_file | grep -E -v -e '( OK|Zip)' >>$err_log
exit_if_err $HERE "Error while checking $zip_file"
}
function check_tgz_file #tgz_file
{
local tgz_file=$1
local HERE=$(ro_here)
log_note $HERE "Check $tgz_file"
ls -l $tgz_file >>$err_log
exit_if_err $HERE "Did not create $tgz_file"
tar -tzf $tgz_file >/dev/null 2>>$err_log
exit_if_err $HERE "Can not extract -- tar -tzf $tgz_file"
}
function convert_to_unix #dir $qhull_2ufiles -- convert files to Unix, preserving modtime from $root_dir
{
local temp_dir=$1
local HERE=$(ro_here)
log_note $HERE "Convert files to unix format in $1"
for f in $(find $temp_dir -type f | grep -E '^([^.]*|.*\.(ac|am|bashrc|c|cfg|cpp|css|d|dpatch|h|htm|html|man|pl|pri|pro|profile|sh|sql|termcap|txt|xml|xsd|xsl))$'); do
exit_if_fail $HERE "d2u '$f' && touch -r '$root_dir/${f#$temp_dir/}' '$f'"
done
for f in $qhull_2ufiles; do
exit_if_fail $HERE "d2u '$temp_dir/$f' && touch -r '$root_dir/$f' '$temp_dir/$f'"
done
}
function create_md5sum #md5_file -- create md5sum of current directory
{
local md5_file=$1
local HERE=$(ro_here)
log_step $HERE "Compute $md5_file"
exit_if_fail $HERE "rm -f $md5_file"
find . -type f | sed 's|^\./||' | sort | xargs md5sum >>$md5_file
exit_if_err $HERE "md5sum failed"
log_note $HERE "$(md5sum $md5_file)"
}
#############################
log_step $LINENO "Configure $0 for $(pwd)/qhull"
#############################
md5_zip_file=qhull-$version-zip.md5sum
md5_tgz_file=qhull-$version-src-tgz.md5sum
# recursive
-qhull_dirs="qhull/config qhull/eg qhull/html qhull/src"
-qhull_files="qhull/build/*.sln qhull/build/*.vcproj \
+qhull_dirs="qhull/eg qhull/html qhull/src"
+qhull_files="qhull/build/*.sln qhull/build/*.vcproj qhull/build/qhulltest/*.vcproj \
qhull/Announce.txt qhull/CMakeLists.txt qhull/COPYING.txt \
qhull/File_id.diz qhull/QHULL-GO.lnk qhull/README.txt \
- qhull/REGISTER.txt qhull/index.htm qhull/Makefile qhull/bin/qhull.dll \
+ qhull/REGISTER.txt qhull/index.htm qhull/Makefile \
qhull/bin/qconvex.exe qhull/bin/qdelaunay.exe qhull/bin/qhalf.exe \
- qhull/bin/qhull.exe qhull/bin/qhull_p.dll qhull/bin/qvoronoi.exe \
+ qhull/bin/qhull.exe qhull/bin/qhull_r.dll qhull/bin/qvoronoi.exe \
qhull/bin/rbox.exe qhull/bin/user_eg.exe qhull/bin/user_eg2.exe \
+ qhull/bin/testqset_r.exe \
qhull/bin/user_eg3.exe qhull/bin/testqset.exe qhull/bin/msvcr80.dll"
qhull_ufiles="$qhull_dirs qhull/build/*.sln qhull/build/*.vcproj \
qhull/Announce.txt qhull/CMakeLists.txt qhull/COPYING.txt \
qhull/File_id.diz qhull/QHULL-GO.lnk qhull/README.txt \
qhull/REGISTER.txt qhull/index.htm qhull/Makefile"
-qhull_d2ufiles="config/changelog config/patches/00list config/Makefile-am-eg \
- config/Makefile-am-html config/Makefile-am-libqhull
- config/Makefile-am-main config/README Makefile src/libqhull/Makefile
+qhull_d2ufiles="Makefile src/libqhull/Makefile src/libqhull_r/Makefile \
+ src/*/DEPRECATED.txt src/*/*.pro src/*/*.htm html/*.htm html/*.txt \
src/libqhull/MBorland eg/q_eg eg/q_egtest eg/q_test "
#############################
log_step $LINENO "Clean distribution directories"
#############################
-if [[ -f qhull/src/Make-config.sh || -d qhull/src/debian ]]; then
- exit_err $LINENO "Before continuing, remove debian build from src/"
-fi
p4 sync -f qhull/build/...
exit_if_err $LINENO "Can not 'p4 sync -f qhull.sln *.vcproj'"
cd qhull && make clean
exit_if_err $LINENO "Can not 'make clean'"
cd ..
+# Includes many files from 'cleanall' (Makefile)
rm -f qhull/src/qhull-all.pro.user* qhull/src/libqhull/BCC32tmp.cfg
rm -f qhull/eg/eg.* qhull/*.x qhull/x.* qhull/x qhull/eg/x
-rm -f qhull/bin/qhulltest.exe qhull/bin/qhulltest qhull/configure.in
+rm -f qhull/bin/qhulltest.exe qhull/bin/qhulltest
rm -f qhull/src/libqhull/*.exe qhull/src/libqhull/*.a
rm -f qhull/src/libqhull/qconvex.c qhull/src/libqhull/unix.c
rm -f qhull/src/libqhull/qdelaun.c qhull/src/libqhull/qhalf.c
rm -f qhull/src/libqhull/qvoronoi.c qhull/src/libqhull/rbox.c
rm -f qhull/src/libqhull/user_eg.c qhull/src/libqhull/user_eg2.c
-rm -f qhull/src/libqhull/testqset.c qhull/Makefile.am
-rm -f qhull/src/libqhull/Makefile.am qhull/html/Makefile.am
-rm -f qhull/src/Makefile.am qhull/eg/Makefile.am
-rm -f qhull/configure.ac
+rm -f qhull/src/libqhull/testqset.c
+rm -f qhull/src/libqhull_r/qconvex_r.c qhull/src/libqhull_r/unix_r.c
+rm -f qhull/src/libqhull_r/qdelaun_r.c qhull/src/libqhull_r/qhalf_r.c
+rm -f qhull/src/libqhull_r/qvoronoi_r.c qhull/src/libqhull_r/rbox_r.c
+rm -f qhull/src/libqhull_r/user_eg_r.c qhull/src/libqhull_r/user_eg2_r.c
+rm -f qhull/src/libqhull_r/testqset_r.c
set noglob
if [[ -e /bin/msysinfo && $(type -p wzzip) && $(type -p wzunzip) ]]; then
#############################
log_step $LINENO "Build zip directory, $TEMP_DIR/qhull"
#############################
ls -l $qhull_files $qhull_dirs >>$err_log
- exit_if_err $LINENO "Missing files for zip directory"
+ exit_if_err $LINENO "Missing files for zip directory. Release build only"
log_note $LINENO "Copy \$qhull_files \$qhull_dirs to $TEMP_DIR/qhull"
exit_if_fail $LINENO "rm -rf $TEMP_DIR && mkdir $TEMP_DIR"
exit_if_fail $LINENO "cp -r -p --parents $qhull_files $qhull_dirs $TEMP_DIR"
#############################
log_step $LINENO "Write md5sum to $md5_tgz_file"
#############################
exit_if_fail $LINENO "pushd $TEMP_DIR/qhull"
create_md5sum $md5_zip_file
exit_if_fail $LINENO "cp -p $md5_zip_file $root_dir"
#############################
log_step $LINENO "Write $qhull_zip_file"
#############################
log_note $LINENO "Write \$qhull_files to $qhull_zip_file"
exit_if_fail $LINENO "cd .. && mv qhull qhull-$version && md5sum qhull-$version/$md5_zip_file >>$root_dir/$qhullmd5_file"
wzzip -P -r -u $qhull_zip_file qhull-$version >>$err_log
exit_if_err $LINENO "wzzip does not exist or error while zipping files"
check_zip_file $qhull_zip_file
exit_if_fail $LINENO "popd"
exit_if_fail $LINENO "mv $TEMP_DIR/$qhull_zip_file ."
fi
#############################
log_step $LINENO "Build tgz directory, $TEMP_DIR/qhull"
#############################
log_note $LINENO "Archive these files as $qhull_tgz_file"
ls -l $qhull_ufiles >>$err_log
exit_if_err $LINENO "Missing files for tgz"
exit_if_fail $LINENO "rm -rf $TEMP_DIR && mkdir -p $TEMP_DIR"
exit_if_fail $LINENO "cp -r -p --parents $qhull_ufiles $TEMP_DIR"
if [[ $IS_WINDOWS && $(type -p d2u) ]]; then
log_step $LINENO "Convert to Unix line endings"
convert_to_unix "$TEMP_DIR"
fi
#############################
log_step $LINENO "Write md5sum to $md5_tgz_file"
#############################
exit_if_fail $LINENO "pushd $TEMP_DIR && cd qhull"
create_md5sum $md5_tgz_file
exit_if_fail $LINENO "cp -p $md5_tgz_file $root_dir"
exit_if_fail $LINENO "cd .. && mv qhull qhull-$version && md5sum qhull-$version/$md5_tgz_file >>$root_dir/$qhullmd5_file"
#############################
log_step $LINENO "Write $qhull_tgz_file"
#############################
exit_if_fail $LINENO "tar -zcf $root_dir/$qhull_tgz_file * && popd"
check_tgz_file $qhull_tgz_file
log_note $LINENO "md5sum of zip and tgz files"
for f in $qhull_zip_file $qhull_tgz_file; do
if [[ -r $f ]]; then
exit_if_fail $LINENO "md5sum $f >>$qhullmd5_file"
fi
done
#############################
log_step $LINENO "Extract zip and tgz files to ($TEMP_DIR)"
#############################
exit_if_fail $LINENO "rm -rf $TEMP_DIR"
if [[ -r $root_dir/$qhull_zip_file ]]; then
exit_if_fail $LINENO "mkdir -p $TEMP_DIR/zip && cd $TEMP_DIR/zip"
exit_if_fail $LINENO "wzunzip -yb -d $root_dir/$qhull_zip_file"
log_step $LINENO "Search for date stamps to zip/Dates.txt"
find . -type f | grep -v '/bin/' | xargs grep '\-20' | grep -v -E '(page=|ISBN|sql-2005|utility-2000|written 2002-2003|tail -n -20|Spinellis|WEBSIDESTORY|D:06-5-2007|server-2005)' >Dates.txt
find . -type f | grep -v '/bin/' | xargs grep -i 'qhull *20' >>Dates.txt
fi
if [[ -r $root_dir/$qhull_tgz_file ]]; then
exit_if_fail $LINENO "mkdir -p $TEMP_DIR/tgz && cd $TEMP_DIR/tgz"
exit_if_fail $LINENO "tar -zxf $root_dir/$qhull_tgz_file"
fi
#############################
+log_step $LINENO "Test qhull -- cd $TEMP_DIR/zip/qhull* && make testall >../q_test.txt 2>&1"
+log_step $LINENO "Build testqhull -- cd /c/bash/local/qhull && bin/qhulltest --all >eg/qhulltest.txt 2>&1"
+log_step $LINENO "Compare eg/q_test-ok.txt to ../test.log"
log_step $LINENO "Compare previous zip release, Dates.txt, and md5sum. Check for virus."
log_step $LINENO "Compare zip and tgz for CRLF vs LF"
log_step $LINENO "Search xml files for UNDEFINED. Check page links"
log_step $LINENO "Extract zip to Qhull/ and compare directories"
log_step $LINENO "Finished successfully"
#############################
diff --git a/eg/qhulltest-ok.txt b/eg/qhulltest-ok.txt
index 8b74a60..5f4a26a 100644
--- a/eg/qhulltest-ok.txt
+++ b/eg/qhulltest-ok.txt
@@ -1,1128 +1,1100 @@
-********* Start testing of orgQhull::QhullVertex_test *********
+********* Start testing of orgQhull::QhullVertexSet_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
-PASS : orgQhull::QhullVertex_test::initTestCase()
-PASS : orgQhull::QhullVertex_test::t_constructConvert()
-5
-3
-2
-1
-6
-0
-7
-8
-XFAIL : orgQhull::QhullVertex_test::t_getSet() ListIterator copy constructor not reset to BOT
-..\..\src\qhulltest\QhullVertex_test.cpp(107) : failure location
-Point 1:
-p1: 0.15707 -0.521517 0.673312
-
-Point 0:
-p0: -0.0992431 0.442941 0.737533
-
-Point 2:
-p2: 0.554717 0.664895 0.0142947
-
-Point 3:
-p3: 0.81103 -0.299563 -0.0499261
-
-Point 6:
-p6: -0.15707 0.521517 -0.673312
-
-Point 4:
-p4: -0.81103 0.299563 0.0499261
-
-Point 5:
-p5: -0.554717 -0.664895 -0.0142947
-
-Point 7:
-p7: 0.0992431 -0.442941 -0.737533
-
-PASS : orgQhull::QhullVertex_test::t_getSet()
-PASS : orgQhull::QhullVertex_test::t_foreach()
-Vertex and vertices w/o runId:
-- p4 (v1): 0.5 -0.5 -0.5
- neighborFacets: f1 f2 f9
- p6(v6) p2(v2) p4(v1) p0(v0)
-Vertex and vertices w/ runId:
-- p4 (v1): 0.5 -0.5 -0.5
- neighborFacets: f1 f2 f9
-vertices: p6(v6) p2(v2) p4(v1) p0(v0)
-
-Try again with simplicial facets. No neighboring facets listed for vertices.
-Vertex and vertices w/o runId:
-- p0 (v5): -0.0222149 -0.366435 0.327062
-This time with neighborFacets() defined for all vertices:
-- p0 (v5): -0.0222149 -0.366435 0.327062
- neighborFacets: f5 f6 f7 f8
-
-Try again with Voronoi diagram of simplicial facets. Neighboring facets automatically defined for vertices.
-Vertex and vertices w/o runId:
-- p7 (v1): 0.386746 0.0449288 0.118336 0.165595
- neighborFacets: f1 f6 f9 f13 f14 f15 f16 f18 f19 f21
-PASS : orgQhull::QhullVertex_test::t_io()
-PASS : orgQhull::QhullVertex_test::cleanupTestCase()
-Totals: 6 passed, 0 failed, 0 skipped
-********* Finished testing of orgQhull::QhullVertex_test *********
+PASS : orgQhull::QhullVertexSet_test::initTestCase()
+INFO : Cube rotated by QR1440989063
+PASS : orgQhull::QhullVertexSet_test::t_construct()
+INFO : Cube rotated by QR1440989063
+PASS : orgQhull::QhullVertexSet_test::t_convert()
+PASS : orgQhull::QhullVertexSet_test::t_readonly()
+INFO : Cube rotated by QR1440989063
+PASS : orgQhull::QhullVertexSet_test::t_foreach()
+INFO : Cube rotated by QR1440989063
+Vertices of first facet with point 0 p7(v6) p1(v3) p5(v2) p3(v0)
+
+Vertex identifiers: v6 v3 v2 v0
+PASS : orgQhull::QhullVertexSet_test::t_io()
+PASS : orgQhull::QhullVertexSet_test::cleanupTestCase()
+Totals: 7 passed, 0 failed, 0 skipped
+********* Finished testing of orgQhull::QhullVertexSet_test *********
********* Start testing of orgQhull::Coordinates_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::Coordinates_test::initTestCase()
PASS : orgQhull::Coordinates_test::t_construct()
PASS : orgQhull::Coordinates_test::t_convert()
PASS : orgQhull::Coordinates_test::t_element()
PASS : orgQhull::Coordinates_test::t_readonly()
PASS : orgQhull::Coordinates_test::t_operator()
PASS : orgQhull::Coordinates_test::t_const_iterator()
PASS : orgQhull::Coordinates_test::t_iterator()
PASS : orgQhull::Coordinates_test::t_coord_iterator()
PASS : orgQhull::Coordinates_test::t_mutable_coord_iterator()
PASS : orgQhull::Coordinates_test::t_readwrite()
PASS : orgQhull::Coordinates_test::t_search()
Coordinates 1-2-3
1 2 3 PASS : orgQhull::Coordinates_test::t_io()
PASS : orgQhull::Coordinates_test::cleanupTestCase()
Totals: 14 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::Coordinates_test *********
********* Start testing of orgQhull::PointCoordinates_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::PointCoordinates_test::initTestCase()
-PASS : orgQhull::PointCoordinates_test::t_construct()
+PASS : orgQhull::PointCoordinates_test::t_construct_q()
+PASS : orgQhull::PointCoordinates_test::t_construct_qh()
PASS : orgQhull::PointCoordinates_test::t_convert()
INFO : Caught QH10063 Qhull error: can not change PointCoordinates dimension (from 3 to 2)
PASS : orgQhull::PointCoordinates_test::t_getset()
PASS : orgQhull::PointCoordinates_test::t_element()
PASS : orgQhull::PointCoordinates_test::t_foreach()
PASS : orgQhull::PointCoordinates_test::t_search()
PASS : orgQhull::PointCoordinates_test::t_modify()
PASS : orgQhull::PointCoordinates_test::t_append_points()
PASS : orgQhull::PointCoordinates_test::t_coord_iterator()
PointCoordinates 0-d
0
0
-PointCoordinates 1-3-2
+PointCoordinates 1,2 3,1 2,3
2
3
1 2
3 1
2 3
PASS : orgQhull::PointCoordinates_test::t_io()
PASS : orgQhull::PointCoordinates_test::cleanupTestCase()
-Totals: 12 passed, 0 failed, 0 skipped
+Totals: 13 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::PointCoordinates_test *********
********* Start testing of orgQhull::QhullFacet_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullFacet_test::initTestCase()
+PASS : orgQhull::QhullFacet_test::t_construct_qh()
PASS : orgQhull::QhullFacet_test::t_constructConvert()
18
19
22
24
26
27
30
31
34
35
38
39
-XFAIL : orgQhull::QhullFacet_test::t_getSet() ListIterator copy constructor not reset to BOT
-..\..\src\qhulltest\QhullFacet_test.cpp(106) : failure location
-Hyperplane: 0.711787 0.143377 0.687607 -0.5
-
-InnerPlane: 0.711787 0.143377 0.687607 -0.5
-innerOffset+0.5 1.16573e-015
-OuterPlane: 0.711787 0.143377 0.687607 -0.5
-outerOffset+0.5 -2.22045e-015
-Center: p10487712: 0.355893 0.0716887 0.343803
-
-Hyperplane: 0.711787 0.143377 0.687607 -0.5
-
-InnerPlane: 0.711787 0.143377 0.687607 -0.5
-innerOffset+0.5 1.16573e-015
-OuterPlane: 0.711787 0.143377 0.687607 -0.5
-outerOffset+0.5 -2.22045e-015
-Center: p10487712: 0.355893 0.0716887 0.343803
-
-Hyperplane: -0.256313 0.964458 0.0642208 -0.5
-
-InnerPlane: -0.256313 0.964458 0.0642208 -0.5
-innerOffset+0.5 1.11022e-015
-OuterPlane: -0.256313 0.964458 0.0642208 -0.5
-outerOffset+0.5 -2.33147e-015
-Center: p10488224: -0.128156 0.482229 0.0321104
-
-Hyperplane: -0.256313 0.964458 0.0642208 -0.5
-
-InnerPlane: -0.256313 0.964458 0.0642208 -0.5
-innerOffset+0.5 1.11022e-015
-OuterPlane: -0.256313 0.964458 0.0642208 -0.5
-outerOffset+0.5 -2.33147e-015
-Center: p10488224: -0.128156 0.482229 0.0321104
-
-Hyperplane: -0.65396 -0.221954 0.723238 -0.5
-
-InnerPlane: -0.65396 -0.221954 0.723238 -0.5
-innerOffset+0.5 1.22125e-015
-OuterPlane: -0.65396 -0.221954 0.723238 -0.5
-outerOffset+0.5 -2.33147e-015
-Center: p10497256: -0.32698 -0.110977 0.361619
-
-Hyperplane: -0.65396 -0.221954 0.723238 -0.5
-
-InnerPlane: -0.65396 -0.221954 0.723238 -0.5
-innerOffset+0.5 1.22125e-015
-OuterPlane: -0.65396 -0.221954 0.723238 -0.5
-outerOffset+0.5 -2.33147e-015
-Center: p10497256: -0.32698 -0.110977 0.361619
-
-Hyperplane: 0.65396 0.221954 -0.723238 -0.5
-
-InnerPlane: 0.65396 0.221954 -0.723238 -0.5
-innerOffset+0.5 1.11022e-015
-OuterPlane: 0.65396 0.221954 -0.723238 -0.5
-outerOffset+0.5 -2.22045e-015
-Center: p10488096: 0.32698 0.110977 -0.361619
-
-Hyperplane: 0.65396 0.221954 -0.723238 -0.5
-
-InnerPlane: 0.65396 0.221954 -0.723238 -0.5
-innerOffset+0.5 1.11022e-015
-OuterPlane: 0.65396 0.221954 -0.723238 -0.5
-outerOffset+0.5 -2.22045e-015
-Center: p10488096: 0.32698 0.110977 -0.361619
-
-Hyperplane: 0.256313 -0.964458 -0.0642208 -0.5
-
-InnerPlane: 0.256313 -0.964458 -0.0642208 -0.5
-innerOffset+0.5 1.22125e-015
-OuterPlane: 0.256313 -0.964458 -0.0642208 -0.5
-outerOffset+0.5 -2.33147e-015
-Center: p10497112: 0.128156 -0.482229 -0.0321104
-
-Hyperplane: 0.256313 -0.964458 -0.0642208 -0.5
-
-InnerPlane: 0.256313 -0.964458 -0.0642208 -0.5
-innerOffset+0.5 1.22125e-015
-OuterPlane: 0.256313 -0.964458 -0.0642208 -0.5
-outerOffset+0.5 -2.33147e-015
-Center: p10497112: 0.128156 -0.482229 -0.0321104
-
-Hyperplane: -0.711787 -0.143377 -0.687607 -0.5
-
-InnerPlane: -0.711787 -0.143377 -0.687607 -0.5
-innerOffset+0.5 1.11022e-015
-OuterPlane: -0.711787 -0.143377 -0.687607 -0.5
-outerOffset+0.5 -2.22045e-015
-Center: p10497280: -0.355893 -0.0716887 -0.343803
-
-Hyperplane: -0.711787 -0.143377 -0.687607 -0.5
-
-InnerPlane: -0.711787 -0.143377 -0.687607 -0.5
-innerOffset+0.5 1.11022e-015
-OuterPlane: -0.711787 -0.143377 -0.687607 -0.5
-outerOffset+0.5 -2.22045e-015
-Center: p10497280: -0.355893 -0.0716887 -0.343803
-
-Voronoi vertex: 0 4.996e-016 4.996e-016
- DistanceEpsilon 1e-012
+Hyperplane: -0.504779 0.784814 0.359534 -0.5
+InnerPlane: -0.504779 0.784814 0.359534 -0.5
+ innerOffset+0.5 1.27676e-015
+OuterPlane: -0.504779 0.784814 0.359534 -0.5
+ outerOffset+0.5 -2.22045e-015
+Center: -0.252389 0.392407 0.179767
+
+Hyperplane: -0.504779 0.784814 0.359534 -0.5
+InnerPlane: -0.504779 0.784814 0.359534 -0.5
+ innerOffset+0.5 1.33227e-015
+OuterPlane: -0.504779 0.784814 0.359534 -0.5
+ outerOffset+0.5 -2.22045e-015
+Center: -0.252389 0.392407 0.179767
+
+Hyperplane: 0.393839 0.579989 -0.713094 -0.5
+InnerPlane: 0.393839 0.579989 -0.713094 -0.5
+ innerOffset+0.5 1.16573e-015
+OuterPlane: 0.393839 0.579989 -0.713094 -0.5
+ outerOffset+0.5 -2.33147e-015
+Center: 0.19692 0.289994 -0.356547
+
+Hyperplane: 0.393839 0.579989 -0.713094 -0.5
+InnerPlane: 0.393839 0.579989 -0.713094 -0.5
+ innerOffset+0.5 1.16573e-015
+OuterPlane: 0.393839 0.579989 -0.713094 -0.5
+ outerOffset+0.5 -2.33147e-015
+Center: 0.19692 0.289994 -0.356547
+
+Hyperplane: -0.768172 -0.218356 -0.601857 -0.5
+InnerPlane: -0.768172 -0.218356 -0.601857 -0.5
+ innerOffset+0.5 1.11022e-015
+OuterPlane: -0.768172 -0.218356 -0.601857 -0.5
+ outerOffset+0.5 -2.44249e-015
+Center: -0.384086 -0.109178 -0.300928
+
+Hyperplane: -0.768172 -0.218356 -0.601857 -0.5
+InnerPlane: -0.768172 -0.218356 -0.601857 -0.5
+ innerOffset+0.5 1.11022e-015
+OuterPlane: -0.768172 -0.218356 -0.601857 -0.5
+ outerOffset+0.5 -2.44249e-015
+Center: -0.384086 -0.109178 -0.300928
+
+Hyperplane: 0.768172 0.218356 0.601857 -0.5
+InnerPlane: 0.768172 0.218356 0.601857 -0.5
+ innerOffset+0.5 1.11022e-015
+OuterPlane: 0.768172 0.218356 0.601857 -0.5
+ outerOffset+0.5 -2.44249e-015
+Center: 0.384086 0.109178 0.300928
+
+Hyperplane: 0.768172 0.218356 0.601857 -0.5
+InnerPlane: 0.768172 0.218356 0.601857 -0.5
+ innerOffset+0.5 1.11022e-015
+OuterPlane: 0.768172 0.218356 0.601857 -0.5
+ outerOffset+0.5 -2.44249e-015
+Center: 0.384086 0.109178 0.300928
+
+Hyperplane: 0.504779 -0.784814 -0.359534 -0.5
+InnerPlane: 0.504779 -0.784814 -0.359534 -0.5
+ innerOffset+0.5 1.33227e-015
+OuterPlane: 0.504779 -0.784814 -0.359534 -0.5
+ outerOffset+0.5 -2.10942e-015
+Center: 0.252389 -0.392407 -0.179767
+
+Hyperplane: 0.504779 -0.784814 -0.359534 -0.5
+InnerPlane: 0.504779 -0.784814 -0.359534 -0.5
+ innerOffset+0.5 1.38778e-015
+OuterPlane: 0.504779 -0.784814 -0.359534 -0.5
+ outerOffset+0.5 -2.10942e-015
+Center: 0.252389 -0.392407 -0.179767
+
+Hyperplane: -0.393839 -0.579989 0.713094 -0.5
+InnerPlane: -0.393839 -0.579989 0.713094 -0.5
+ innerOffset+0.5 1.16573e-015
+OuterPlane: -0.393839 -0.579989 0.713094 -0.5
+ outerOffset+0.5 -2.22045e-015
+Center: -0.19692 -0.289994 0.356547
+
+Hyperplane: -0.393839 -0.579989 0.713094 -0.5
+InnerPlane: -0.393839 -0.579989 0.713094 -0.5
+ innerOffset+0.5 1.16573e-015
+OuterPlane: -0.393839 -0.579989 0.713094 -0.5
+ outerOffset+0.5 -2.22045e-015
+Center: -0.19692 -0.289994 0.356547
+
+Voronoi vertex: -1.11022e-016 -4.92661e-016 -2.77556e-016
+ DistanceEpsilon 1.7168e-013
PASS : orgQhull::QhullFacet_test::t_getSet()
PASS : orgQhull::QhullFacet_test::t_value()
PASS : orgQhull::QhullFacet_test::t_foreach()
- f1
- flags: bottom tested seen coplanar
- merges: 1
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- vertices: p6(v6) p2(v2) p4(v1) p0(v0)
- neighboring facets: f2 f3 f9 f10
- ridges:
- r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
- r3 tested
vertices: p4(v1) p0(v0)
between f2 and f1
- r1 tested
vertices: p6(v6) p4(v1)
between f9 and f1
- r2 tested
vertices: p6(v6) p2(v2)
between f1 and f10
+
+With a message
+- f1
+ - flags: bottom tested seen coplanar
+ - merges: 1
+ - normal: -0 -0 -1
+ - offset: -0.5
+ - center: 0 0 -0.5
+ - vertices: p6(v6) p2(v2) p4(v1) p0(v0)
+ - neighboring facets: f2 f3 f9 f10
+ - ridges:
+ - r4 tested
+ vertices: p2(v2) p0(v0)
+ between f1 and f3
+ - r3 tested
+ vertices: p4(v1) p0(v0)
+ between f2 and f1
+ - r1 tested
+ vertices: p6(v6) p4(v1)
+ between f9 and f1
+ - r2 tested
+ vertices: p6(v6) p2(v2)
+ between f1 and f10
+
+Print header for the same facet
- f1
- flags: bottom tested seen coplanar
- merges: 1
- normal: -0 -0 -1
- offset: -0.5
- center: 0 0 -0.5
- vertices: p6(v6) p2(v2) p4(v1) p0(v0)
- neighboring facets: f2 f3 f9 f10
+
+Print each component
- flags: bottom tested seen coplanar
- - center:0 0 -0.5
+ - center: 0 0 -0.5
- ridges:
- r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
- r3 tested
vertices: p4(v1) p0(v0)
between f2 and f1
- r1 tested
vertices: p6(v6) p4(v1)
between f9 and f1
- r2 tested
vertices: p6(v6) p2(v2)
between f1 and f10
PASS : orgQhull::QhullFacet_test::t_io()
PASS : orgQhull::QhullFacet_test::cleanupTestCase()
-Totals: 7 passed, 0 failed, 0 skipped
+Totals: 8 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullFacet_test *********
********* Start testing of orgQhull::QhullFacetList_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullFacetList_test::initTestCase()
-PASS : orgQhull::QhullFacetList_test::t_construct()
+PASS : orgQhull::QhullFacetList_test::t_construct_qh()
+PASS : orgQhull::QhullFacetList_test::t_construct_q()
PASS : orgQhull::QhullFacetList_test::t_convert()
PASS : orgQhull::QhullFacetList_test::t_readonly()
PASS : orgQhull::QhullFacetList_test::t_foreach()
+Show all of FacetList
Vertices for 3 facets
-- p1 (v5): 0.15707 -0.521517 0.673312
- neighborFacets: f6 f4 f11
-- p0 (v3): -0.0992431 0.442941 0.737533
- neighborFacets: f3 f4 f6
-- p2 (v2): 0.554717 0.664895 0.0142947
- neighborFacets: f3 f4 f8
-- p3 (v1): 0.81103 -0.299563 -0.0499261
- neighborFacets: f4 f8 f11
-- p6 (v6): -0.15707 0.521517 -0.673312
- neighborFacets: f8 f3 f13
-- p4 (v0): -0.81103 0.299563 0.0499261
- neighborFacets: f3 f6 f13
-- p5 (v7): -0.554717 -0.664895 -0.0142947
- neighborFacets: f11 f6 f13
+- p0 (v8): 0.439556 -0.573223 0.477709
+ neighborFacets: f4 f14 f12
+- p1 (v3): -0.0652231 0.211591 0.837243
+ neighborFacets: f3 f4 f12
+- p5 (v2): 0.328616 0.79158 0.124148
+ neighborFacets: f3 f4 f7
+- p4 (v1): 0.833395 0.00676534 -0.235386
+ neighborFacets: f4 f7 f14
+- p2 (v7): -0.328616 -0.79158 -0.124148
+ neighborFacets: f12 f8 f14
+- p6 (v5): 0.0652231 -0.211591 -0.837243
+ neighborFacets: f7 f8 f14
+- p3 (v0): -0.833395 -0.00676534 0.235386
+ neighborFacets: f3 f8 f12
- f4
- - flags: top tested seen
- - merges: 1
- - normal: 0.711787 0.143377 0.687607
- - offset: -0.5
- - center: 0.355893 0.0716887 0.343803
- - vertices: p1(v5) p0(v3) p2(v2) p3(v1)
- - neighboring facets: f8 f3 f11 f6
- - ridges:
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- - r3 tested
- vertices: p2(v2) p3(v1)
- between f4 and f8
- - r1 tested
- vertices: p1(v5) p3(v1)
- between f11 and f4
- - r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
-- f3
- - flags: bottom tested seen
+ - flags: top tested seen coplanar
- merges: 1
- - normal: -0.256313 0.964458 0.0642208
+ - normal: 0.768172 0.218356 0.601857
- offset: -0.5
- - center: -0.128156 0.482229 0.0321104
- - vertices: p6(v6) p0(v3) p2(v2) p4(v0)
- - neighboring facets: f13 f6 f4 f8
+ - center: 0.384086 0.109178 0.300928
+ - vertices: p0(v8) p1(v3) p5(v2) p4(v1)
+ - neighboring facets: f7 f3 f14 f12
- ridges:
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
- - r6 tested
- vertices: p6(v6) p4(v0)
- between f13 and f3
- - r10 tested
- vertices: p6(v6) p2(v2)
- between f3 and f8
-- f6
+ vertices: p5(v2) p4(v1)
+ between f4 and f7
+ - r16 tested
+ vertices: p0(v8) p4(v1)
+ between f14 and f4
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r8 tested
+ vertices: p1(v3) p5(v2)
+ between f4 and f3
+- f14
- flags: bottom tested seen coplanar
- merges: 1
- - normal: -0.65396 -0.221954 0.723238
+ - normal: 0.504779 -0.784814 -0.359534
- offset: -0.5
- - center: -0.32698 -0.110977 0.361619
- - vertices: p5(v7) p1(v5) p0(v3) p4(v0)
- - neighboring facets: f3 f4 f13 f11
+ - center: 0.252389 -0.392407 -0.179767
+ - vertices: p0(v8) p2(v7) p6(v5) p4(v1)
+ - neighboring facets: f7 f4 f8 f12
- ridges:
- r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
+ vertices: p6(v5) p4(v1)
+ between f7 and f14
- r14 tested
- vertices: p5(v7) p1(v5)
- between f11 and f6
- - r13 tested
- vertices: p5(v7) p4(v0)
- between f6 and f13
- - r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
-
-Facets only
-- f4
- - flags: top tested seen
+ vertices: p2(v7) p6(v5)
+ between f8 and f14
+ - r19 tested
+ vertices: p0(v8) p2(v7)
+ between f12 and f14
+ - r16 tested
+ vertices: p0(v8) p4(v1)
+ between f14 and f4
+- f12
+ - flags: bottom tested coplanar
- merges: 1
- - normal: 0.711787 0.143377 0.687607
+ - normal: -0.393839 -0.579989 0.713094
- offset: -0.5
- - center: 0.355893 0.0716887 0.343803
- - vertices: p1(v5) p0(v3) p2(v2) p3(v1)
- - neighboring facets: f8 f3 f11 f6
+ - center: -0.19692 -0.289994 0.356547
+ - vertices: p0(v8) p2(v7) p1(v3) p3(v0)
+ - neighboring facets: f3 f8 f14 f4
- ridges:
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- r3 tested
- vertices: p2(v2) p3(v1)
- between f4 and f8
- - r1 tested
- vertices: p1(v5) p3(v1)
- between f11 and f4
- - r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
-- f3
- - flags: bottom tested seen
+ vertices: p1(v3) p3(v0)
+ between f3 and f12
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r19 tested
+ vertices: p0(v8) p2(v7)
+ between f12 and f14
+ - r13 tested
+ vertices: p2(v7) p3(v0)
+ between f12 and f8
+
+Facets only
+- f4
+ - flags: top tested seen coplanar
- merges: 1
- - normal: -0.256313 0.964458 0.0642208
+ - normal: 0.768172 0.218356 0.601857
- offset: -0.5
- - center: -0.128156 0.482229 0.0321104
- - vertices: p6(v6) p0(v3) p2(v2) p4(v0)
- - neighboring facets: f13 f6 f4 f8
+ - center: 0.384086 0.109178 0.300928
+ - vertices: p0(v8) p1(v3) p5(v2) p4(v1)
+ - neighboring facets: f7 f3 f14 f12
- ridges:
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
- - r6 tested
- vertices: p6(v6) p4(v0)
- between f13 and f3
- - r10 tested
- vertices: p6(v6) p2(v2)
- between f3 and f8
-- f6
+ vertices: p5(v2) p4(v1)
+ between f4 and f7
+ - r16 tested
+ vertices: p0(v8) p4(v1)
+ between f14 and f4
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r8 tested
+ vertices: p1(v3) p5(v2)
+ between f4 and f3
+- f14
- flags: bottom tested seen coplanar
- merges: 1
- - normal: -0.65396 -0.221954 0.723238
+ - normal: 0.504779 -0.784814 -0.359534
- offset: -0.5
- - center: -0.32698 -0.110977 0.361619
- - vertices: p5(v7) p1(v5) p0(v3) p4(v0)
- - neighboring facets: f3 f4 f13 f11
+ - center: 0.252389 -0.392407 -0.179767
+ - vertices: p0(v8) p2(v7) p6(v5) p4(v1)
+ - neighboring facets: f7 f4 f8 f12
- ridges:
- r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
+ vertices: p6(v5) p4(v1)
+ between f7 and f14
- r14 tested
- vertices: p5(v7) p1(v5)
- between f11 and f6
+ vertices: p2(v7) p6(v5)
+ between f8 and f14
+ - r19 tested
+ vertices: p0(v8) p2(v7)
+ between f12 and f14
+ - r16 tested
+ vertices: p0(v8) p4(v1)
+ between f14 and f4
+- f12
+ - flags: bottom tested coplanar
+ - merges: 1
+ - normal: -0.393839 -0.579989 0.713094
+ - offset: -0.5
+ - center: -0.19692 -0.289994 0.356547
+ - vertices: p0(v8) p2(v7) p1(v3) p3(v0)
+ - neighboring facets: f3 f8 f14 f4
+ - ridges:
+ - r3 tested
+ vertices: p1(v3) p3(v0)
+ between f3 and f12
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r19 tested
+ vertices: p0(v8) p2(v7)
+ between f12 and f14
- r13 tested
- vertices: p5(v7) p4(v0)
- between f6 and f13
- - r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
+ vertices: p2(v7) p3(v0)
+ between f12 and f8
+
+Vertices only
+- p0 (v8): 0.439556 -0.573223 0.477709
+ neighborFacets: f4 f14 f12
+- p1 (v3): -0.0652231 0.211591 0.837243
+ neighborFacets: f3 f4 f12
+- p5 (v2): 0.328616 0.79158 0.124148
+ neighborFacets: f3 f4 f7
+- p4 (v1): 0.833395 0.00676534 -0.235386
+ neighborFacets: f4 f7 f14
+- p2 (v7): -0.328616 -0.79158 -0.124148
+ neighborFacets: f12 f8 f14
+- p6 (v5): 0.0652231 -0.211591 -0.837243
+ neighborFacets: f7 f8 f14
+- p3 (v0): -0.833395 -0.00676534 0.235386
+ neighborFacets: f3 f8 f12
PASS : orgQhull::QhullFacetList_test::t_io()
PASS : orgQhull::QhullFacetList_test::cleanupTestCase()
-Totals: 7 passed, 0 failed, 0 skipped
+Totals: 8 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullFacetList_test *********
********* Start testing of orgQhull::QhullFacetSet_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullFacetSet_test::initTestCase()
PASS : orgQhull::QhullFacetSet_test::t_construct()
PASS : orgQhull::QhullFacetSet_test::t_convert()
PASS : orgQhull::QhullFacetSet_test::t_readonly()
PASS : orgQhull::QhullFacetSet_test::t_foreach()
-- f3
- - flags: bottom tested seen
+Neighbors of first facet with point 0- f4
+ - flags: top tested seen coplanar
- merges: 1
- - normal: -0.256313 0.964458 0.0642208
+ - normal: 0.768172 0.218356 0.601857
- offset: -0.5
- - center: -0.128156 0.482229 0.0321104
- - vertices: p6(v6) p0(v3) p2(v2) p4(v0)
- - neighboring facets: f13 f6 f4 f8
+ - center: 0.384086 0.109178 0.300928
+ - vertices: p0(v8) p1(v3) p5(v2) p4(v1)
+ - neighboring facets: f7 f3 f14 f12
- ridges:
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
- - r6 tested
- vertices: p6(v6) p4(v0)
- between f13 and f3
- - r10 tested
- vertices: p6(v6) p2(v2)
- between f3 and f8
-- f6
- - flags: bottom tested seen coplanar
+ vertices: p5(v2) p4(v1)
+ between f4 and f7
+ - r16 tested
+ vertices: p0(v8) p4(v1)
+ between f14 and f4
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r8 tested
+ vertices: p1(v3) p5(v2)
+ between f4 and f3
+- f12
+ - flags: bottom tested coplanar
- merges: 1
- - normal: -0.65396 -0.221954 0.723238
+ - normal: -0.393839 -0.579989 0.713094
- offset: -0.5
- - center: -0.32698 -0.110977 0.361619
- - vertices: p5(v7) p1(v5) p0(v3) p4(v0)
- - neighboring facets: f3 f4 f13 f11
+ - center: -0.19692 -0.289994 0.356547
+ - vertices: p0(v8) p2(v7) p1(v3) p3(v0)
+ - neighboring facets: f3 f8 f14 f4
- ridges:
- - r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
- - r14 tested
- vertices: p5(v7) p1(v5)
- between f11 and f6
+ - r3 tested
+ vertices: p1(v3) p3(v0)
+ between f3 and f12
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r19 tested
+ vertices: p0(v8) p2(v7)
+ between f12 and f14
- r13 tested
- vertices: p5(v7) p4(v0)
- between f6 and f13
- - r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
+ vertices: p2(v7) p3(v0)
+ between f12 and f8
-Facet identifiers: f3 f6
+Facet identifiers: f4 f12
PASS : orgQhull::QhullFacetSet_test::t_io()
PASS : orgQhull::QhullFacetSet_test::cleanupTestCase()
Totals: 7 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullFacetSet_test *********
********* Start testing of orgQhull::QhullHyperplane_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullHyperplane_test::initTestCase()
PASS : orgQhull::QhullHyperplane_test::t_construct()
+PASS : orgQhull::QhullHyperplane_test::t_construct_qh()
PASS : orgQhull::QhullHyperplane_test::t_convert()
h18
h19
h22
h24
h26
h27
h30
h31
h34
h35
h38
h39
PASS : orgQhull::QhullHyperplane_test::t_readonly()
PASS : orgQhull::QhullHyperplane_test::t_define()
+angle 2.77556e-016
PASS : orgQhull::QhullHyperplane_test::t_value()
PASS : orgQhull::QhullHyperplane_test::t_operator()
PASS : orgQhull::QhullHyperplane_test::t_iterator()
PASS : orgQhull::QhullHyperplane_test::t_const_iterator()
PASS : orgQhull::QhullHyperplane_test::t_qhullHyperplane_iterator()
Hyperplane:
-0 -0 -1 -0.5
-Hyperplane w/ runId:
- -0 -0 -1 -0.5
+message -0 -0 -1 -0.5
and a message -0 -0 -1 offset -0.5
PASS : orgQhull::QhullHyperplane_test::t_io()
PASS : orgQhull::QhullHyperplane_test::cleanupTestCase()
-Totals: 12 passed, 0 failed, 0 skipped
+Totals: 13 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullHyperplane_test *********
********* Start testing of orgQhull::QhullLinkedList_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullLinkedList_test::initTestCase()
PASS : orgQhull::QhullLinkedList_test::t_construct()
PASS : orgQhull::QhullLinkedList_test::t_convert()
PASS : orgQhull::QhullLinkedList_test::t_element()
PASS : orgQhull::QhullLinkedList_test::t_search()
PASS : orgQhull::QhullLinkedList_test::t_iterator()
PASS : orgQhull::QhullLinkedList_test::t_const_iterator()
PASS : orgQhull::QhullLinkedList_test::t_QhullLinkedList_iterator()
INFO: empty QhullVertextList
-INFO: - p0 (v3): -0.0992431 0.442941 0.737533
- neighborFacets: f3 f4 f6
-- p7 (v8): 0.0992431 -0.442941 -0.737533
- neighborFacets: f8 f11 f13
-- p6 (v6): -0.15707 0.521517 -0.673312
- neighborFacets: f8 f3 f13
-- p3 (v1): 0.81103 -0.299563 -0.0499261
- neighborFacets: f4 f8 f11
-- p5 (v7): -0.554717 -0.664895 -0.0142947
- neighborFacets: f11 f6 f13
-- p2 (v2): 0.554717 0.664895 0.0142947
- neighborFacets: f3 f4 f8
-- p1 (v5): 0.15707 -0.521517 0.673312
- neighborFacets: f6 f4 f11
-- p4 (v0): -0.81103 0.299563 0.0499261
- neighborFacets: f3 f6 f13
+INFO: - p7 (v6): -0.439556 0.573223 -0.477709
+ neighborFacets: f8 f3 f7
+- p0 (v8): 0.439556 -0.573223 0.477709
+ neighborFacets: f4 f14 f12
+- p1 (v3): -0.0652231 0.211591 0.837243
+ neighborFacets: f3 f4 f12
+- p4 (v1): 0.833395 0.00676534 -0.235386
+ neighborFacets: f4 f7 f14
+- p2 (v7): -0.328616 -0.79158 -0.124148
+ neighborFacets: f12 f8 f14
+- p5 (v2): 0.328616 0.79158 0.124148
+ neighborFacets: f3 f4 f7
+- p6 (v5): 0.0652231 -0.211591 -0.837243
+ neighborFacets: f7 f8 f14
+- p3 (v0): -0.833395 -0.00676534 0.235386
+ neighborFacets: f3 f8 f12
PASS : orgQhull::QhullLinkedList_test::t_io()
PASS : orgQhull::QhullLinkedList_test::cleanupTestCase()
Totals: 10 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullLinkedList_test *********
********* Start testing of orgQhull::QhullPoint_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullPoint_test::initTestCase()
PASS : orgQhull::QhullPoint_test::t_construct()
PASS : orgQhull::QhullPoint_test::t_convert()
+Point ids in 'rbox c'
+p7
p1
-p0
-p2
p3
+p5
p6
p4
-p5
-p7
+p2
+p0
PASS : orgQhull::QhullPoint_test::t_readonly()
PASS : orgQhull::QhullPoint_test::t_define()
PASS : orgQhull::QhullPoint_test::t_operator()
PASS : orgQhull::QhullPoint_test::t_iterator()
PASS : orgQhull::QhullPoint_test::t_const_iterator()
PASS : orgQhull::QhullPoint_test::t_qhullpoint_iterator()
-Point w/o runId:
-p4: 0.5 -0.5 -0.5
-Point w/ runId:
-p4: 0.5 -0.5 -0.5
- and a message 0.5 -0.5 -0.5
+PASS : orgQhull::QhullPoint_test::t_method()
+Point:
+ 0.5 -0.5 -0.5
+Point w/ print:
+ message 0.5 -0.5 -0.5
Point with id and a message p4: 0.5 -0.5 -0.5
PASS : orgQhull::QhullPoint_test::t_io()
PASS : orgQhull::QhullPoint_test::cleanupTestCase()
-Totals: 11 passed, 0 failed, 0 skipped
+Totals: 12 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullPoint_test *********
********* Start testing of orgQhull::QhullPoints_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullPoints_test::initTestCase()
-PASS : orgQhull::QhullPoints_test::t_construct()
+PASS : orgQhull::QhullPoints_test::t_construct_q()
+PASS : orgQhull::QhullPoints_test::t_construct_qh()
PASS : orgQhull::QhullPoints_test::t_convert()
PASS : orgQhull::QhullPoints_test::t_getset()
PASS : orgQhull::QhullPoints_test::t_element()
PASS : orgQhull::QhullPoints_test::t_iterator()
PASS : orgQhull::QhullPoints_test::t_const_iterator()
PASS : orgQhull::QhullPoints_test::t_search()
PASS : orgQhull::QhullPoints_test::t_points_iterator()
Empty QhullPoints
QhullPoints from c[]
-p1241312: 0 1 2
-p1241336: 3 4 5
+ 0 1 2
+ 3 4 5
QhullPoints
-p0: -0.0992431 0.442941 0.737533
-p1: 0.15707 -0.521517 0.673312
-p2: 0.554717 0.664895 0.0142947
-p3: 0.81103 -0.299563 -0.0499261
-p4: -0.81103 0.299563 0.0499261
-p5: -0.554717 -0.664895 -0.0142947
-p6: -0.15707 0.521517 -0.673312
-p7: 0.0992431 -0.442941 -0.737533
-RunId
-p0: -0.0992431 0.442941 0.737533
-p1: 0.15707 -0.521517 0.673312
-p2: 0.554717 0.664895 0.0142947
-p3: 0.81103 -0.299563 -0.0499261
-p4: -0.81103 0.299563 0.0499261
-p5: -0.554717 -0.664895 -0.0142947
-p6: -0.15707 0.521517 -0.673312
-p7: 0.0992431 -0.442941 -0.737533
-RunId w/ message
- -0.0992431 0.442941 0.737533
- 0.15707 -0.521517 0.673312
- 0.554717 0.664895 0.0142947
- 0.81103 -0.299563 -0.0499261
- -0.81103 0.299563 0.0499261
- -0.554717 -0.664895 -0.0142947
- -0.15707 0.521517 -0.673312
- 0.0992431 -0.442941 -0.737533
-RunId w/ identifiers
-p0: -0.0992431 0.442941 0.737533
-p1: 0.15707 -0.521517 0.673312
-p2: 0.554717 0.664895 0.0142947
-p3: 0.81103 -0.299563 -0.0499261
-p4: -0.81103 0.299563 0.0499261
-p5: -0.554717 -0.664895 -0.0142947
-p6: -0.15707 0.521517 -0.673312
-p7: 0.0992431 -0.442941 -0.737533
+ 0.439556 -0.573223 0.477709
+ -0.0652231 0.211591 0.837243
+ -0.328616 -0.79158 -0.124148
+ -0.833395 -0.00676534 0.235386
+ 0.833395 0.00676534 -0.235386
+ 0.328616 0.79158 0.124148
+ 0.0652231 -0.211591 -0.837243
+ -0.439556 0.573223 -0.477709
+message
+ 0.439556 -0.573223 0.477709
+ -0.0652231 0.211591 0.837243
+ -0.328616 -0.79158 -0.124148
+ -0.833395 -0.00676534 0.235386
+ 0.833395 0.00676534 -0.235386
+ 0.328616 0.79158 0.124148
+ 0.0652231 -0.211591 -0.837243
+ -0.439556 0.573223 -0.477709
+w/ identifiers
+p0: 0.439556 -0.573223 0.477709
+p1: -0.0652231 0.211591 0.837243
+p2: -0.328616 -0.79158 -0.124148
+p3: -0.833395 -0.00676534 0.235386
+p4: 0.833395 0.00676534 -0.235386
+p5: 0.328616 0.79158 0.124148
+p6: 0.0652231 -0.211591 -0.837243
+p7: -0.439556 0.573223 -0.477709
PASS : orgQhull::QhullPoints_test::t_io()
PASS : orgQhull::QhullPoints_test::cleanupTestCase()
-Totals: 11 passed, 0 failed, 0 skipped
+Totals: 12 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullPoints_test *********
********* Start testing of orgQhull::QhullPointSet_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullPointSet_test::initTestCase()
PASS : orgQhull::QhullPointSet_test::t_construct()
PASS : orgQhull::QhullPointSet_test::t_convert()
PASS : orgQhull::QhullPointSet_test::t_element()
PASS : orgQhull::QhullPointSet_test::t_iterator()
PASS : orgQhull::QhullPointSet_test::t_const_iterator()
PASS : orgQhull::QhullPointSet_test::t_search()
PASS : orgQhull::QhullPointSet_test::t_pointset_iterator()
QhullPointSet from coplanarPoints
-p21: 0.368247 0.129543 0.5
-p51: 0.35127 -0.210684 0.5
-p80: 0.313266 0.0568358 0.5
-p27: 0.0344498 -0.00151988 0.5
-p34: -0.000258967 -0.352467 0.5
-p19: 0.44098 -0.449916 0.5
-p57: -0.300445 0.416634 0.5
-p97: -0.336919 0.403301 0.5
-p108: -0.442525 0.486883 0.5
-p48: 0.100394 0.317561 0.5
-p50: 0.188981 0.202207 0.5
-p75: 0.196243 0.25294 0.5
-p5: -0.082514 0.186773 0.5
-p12: -0.22729 -0.0635886 0.5
-p23: -0.148985 0.0132737 0.5
-p29: -0.340232 -0.287248 0.5
-p87: -0.17844 -0.0395658 0.5
-p100: -0.114231 0.126861 0.5
-p7: -0.0840006 0.201191 0.5
-p0: -0.499992 -0.368462 0.5
-p110: 0.076173 0.238959 0.5
-p28: 0.0545838 0.390737 0.5
-p15: 0.404653 0.00452289 0.5
-
-
-RunId
-p21: 0.368247 0.129543 0.5
-p51: 0.35127 -0.210684 0.5
-p80: 0.313266 0.0568358 0.5
-p27: 0.0344498 -0.00151988 0.5
-p34: -0.000258967 -0.352467 0.5
-p19: 0.44098 -0.449916 0.5
-p57: -0.300445 0.416634 0.5
-p97: -0.336919 0.403301 0.5
-p108: -0.442525 0.486883 0.5
-p48: 0.100394 0.317561 0.5
-p50: 0.188981 0.202207 0.5
-p75: 0.196243 0.25294 0.5
-p5: -0.082514 0.186773 0.5
-p12: -0.22729 -0.0635886 0.5
-p23: -0.148985 0.0132737 0.5
-p29: -0.340232 -0.287248 0.5
-p87: -0.17844 -0.0395658 0.5
-p100: -0.114231 0.126861 0.5
-p7: -0.0840006 0.201191 0.5
-p0: -0.499992 -0.368462 0.5
-p110: 0.076173 0.238959 0.5
-p28: 0.0545838 0.390737 0.5
-p15: 0.404653 0.00452289 0.5
-
-RunId w/ message
-p21: 0.368247 0.129543 0.5
-p51: 0.35127 -0.210684 0.5
-p80: 0.313266 0.0568358 0.5
-p27: 0.0344498 -0.00151988 0.5
-p34: -0.000258967 -0.352467 0.5
-p19: 0.44098 -0.449916 0.5
-p57: -0.300445 0.416634 0.5
-p97: -0.336919 0.403301 0.5
-p108: -0.442525 0.486883 0.5
-p48: 0.100394 0.317561 0.5
-p50: 0.188981 0.202207 0.5
-p75: 0.196243 0.25294 0.5
-p5: -0.082514 0.186773 0.5
-p12: -0.22729 -0.0635886 0.5
-p23: -0.148985 0.0132737 0.5
-p29: -0.340232 -0.287248 0.5
-p87: -0.17844 -0.0395658 0.5
-p100: -0.114231 0.126861 0.5
-p7: -0.0840006 0.201191 0.5
-p0: -0.499992 -0.368462 0.5
-p110: 0.076173 0.238959 0.5
-p28: 0.0545838 0.390737 0.5
-p15: 0.404653 0.00452289 0.5
+ 0.368247 0.129543 0.5
+ 0.35127 -0.210684 0.5
+ 0.313266 0.0568358 0.5
+ 0.0344498 -0.00151988 0.5
+ -0.000258967 -0.352467 0.5
+ 0.44098 -0.449916 0.5
+ -0.300445 0.416634 0.5
+ -0.336919 0.403301 0.5
+ -0.442525 0.486883 0.5
+ 0.100394 0.317561 0.5
+ 0.188981 0.202207 0.5
+ 0.196243 0.25294 0.5
+ -0.082514 0.186773 0.5
+ -0.22729 -0.0635886 0.5
+ -0.148985 0.0132737 0.5
+ -0.340232 -0.287248 0.5
+ -0.17844 -0.0395658 0.5
+ -0.114231 0.126861 0.5
+ -0.0840006 0.201191 0.5
+ -0.499992 -0.368462 0.5
+ 0.076173 0.238959 0.5
+ 0.0545838 0.390737 0.5
+ 0.404653 0.00452289 0.5
+
+
+With message
+ 0.368247 0.129543 0.5
+ 0.35127 -0.210684 0.5
+ 0.313266 0.0568358 0.5
+ 0.0344498 -0.00151988 0.5
+ -0.000258967 -0.352467 0.5
+ 0.44098 -0.449916 0.5
+ -0.300445 0.416634 0.5
+ -0.336919 0.403301 0.5
+ -0.442525 0.486883 0.5
+ 0.100394 0.317561 0.5
+ 0.188981 0.202207 0.5
+ 0.196243 0.25294 0.5
+ -0.082514 0.186773 0.5
+ -0.22729 -0.0635886 0.5
+ -0.148985 0.0132737 0.5
+ -0.340232 -0.287248 0.5
+ -0.17844 -0.0395658 0.5
+ -0.114231 0.126861 0.5
+ -0.0840006 0.201191 0.5
+ -0.499992 -0.368462 0.5
+ 0.076173 0.238959 0.5
+ 0.0545838 0.390737 0.5
+ 0.404653 0.00452289 0.5
+
+Coplanar points: p21 p51 p80 p27 p34 p19 p57 p97 p108 p48 p50 p75 p5 p12 p23 p29 p87 p100 p7 p0 p110 p28 p15
+
+As a point set:
+ 0.368247 0.129543 0.5
+ 0.35127 -0.210684 0.5
+ 0.313266 0.0568358 0.5
+ 0.0344498 -0.00151988 0.5
+ -0.000258967 -0.352467 0.5
+ 0.44098 -0.449916 0.5
+ -0.300445 0.416634 0.5
+ -0.336919 0.403301 0.5
+ -0.442525 0.486883 0.5
+ 0.100394 0.317561 0.5
+ 0.188981 0.202207 0.5
+ 0.196243 0.25294 0.5
+ -0.082514 0.186773 0.5
+ -0.22729 -0.0635886 0.5
+ -0.148985 0.0132737 0.5
+ -0.340232 -0.287248 0.5
+ -0.17844 -0.0395658 0.5
+ -0.114231 0.126861 0.5
+ -0.0840006 0.201191 0.5
+ -0.499992 -0.368462 0.5
+ 0.076173 0.238959 0.5
+ 0.0545838 0.390737 0.5
+ 0.404653 0.00452289 0.5
PASS : orgQhull::QhullPointSet_test::t_io()
PASS : orgQhull::QhullPointSet_test::cleanupTestCase()
Totals: 10 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullPointSet_test *********
********* Start testing of orgQhull::QhullRidge_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullRidge_test::initTestCase()
PASS : orgQhull::QhullRidge_test::t_construct()
-4
3
-1
-2
-XFAIL : orgQhull::QhullRidge_test::t_getSet() SetIterator copy constructor not reset to BOT
-..\..\src\qhulltest\QhullRidge_test.cpp(105) : failure location
+8
+6
+7
PASS : orgQhull::QhullRidge_test::t_getSet()
PASS : orgQhull::QhullRidge_test::t_foreach()
-Ridges Without runId
+Ridges
- r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
- r3 tested
vertices: p4(v1) p0(v0)
between f2 and f1
- r1 tested
vertices: p6(v6) p4(v1)
between f9 and f1
- r2 tested
vertices: p6(v6) p2(v2)
between f1 and f10
Ridge
- r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
-Ridge with runId
- - r4 tested
+
+Ridge with message r4 tested
vertices: p2(v2) p0(v0)
between f1 and f3
PASS : orgQhull::QhullRidge_test::t_io()
PASS : orgQhull::QhullRidge_test::cleanupTestCase()
Totals: 6 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullRidge_test *********
********* Start testing of orgQhull::QhullSet_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullSet_test::initTestCase()
PASS : orgQhull::QhullSet_test::t_qhullsetbase()
PASS : orgQhull::QhullSet_test::t_convert()
PASS : orgQhull::QhullSet_test::t_element()
PASS : orgQhull::QhullSet_test::t_search()
PASS : orgQhull::QhullSet_test::t_iterator()
PASS : orgQhull::QhullSet_test::t_const_iterator()
PASS : orgQhull::QhullSet_test::t_qhullset_iterator()
INFO: empty set
INFO: Neighboring facets
-- f8
- - flags: bottom tested seen coplanar
+- f4
+ - flags: top tested seen coplanar
- merges: 1
- - normal: 0.65396 0.221954 -0.723238
+ - normal: 0.768172 0.218356 0.601857
- offset: -0.5
- - center: 0.32698 0.110977 -0.361619
- - vertices: p7(v8) p6(v6) p2(v2) p3(v1)
- - neighboring facets: f4 f3 f11 f13
+ - center: 0.384086 0.109178 0.300928
+ - vertices: p0(v8) p1(v3) p5(v2) p4(v1)
+ - neighboring facets: f7 f3 f14 f12
- ridges:
- - r3 tested
- vertices: p2(v2) p3(v1)
- between f4 and f8
- - r10 tested
- vertices: p6(v6) p2(v2)
- between f3 and f8
- - r17 tested
- vertices: p7(v8) p6(v6)
- between f13 and f8
+ - r11 tested
+ vertices: p5(v2) p4(v1)
+ between f4 and f7
- r16 tested
- vertices: p7(v8) p3(v1)
- between f8 and f11
-- f3
- - flags: bottom tested seen
+ vertices: p0(v8) p4(v1)
+ between f14 and f4
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r8 tested
+ vertices: p1(v3) p5(v2)
+ between f4 and f3
+- f12
+ - flags: bottom tested coplanar
- merges: 1
- - normal: -0.256313 0.964458 0.0642208
+ - normal: -0.393839 -0.579989 0.713094
- offset: -0.5
- - center: -0.128156 0.482229 0.0321104
- - vertices: p6(v6) p0(v3) p2(v2) p4(v0)
- - neighboring facets: f13 f6 f4 f8
+ - center: -0.19692 -0.289994 0.356547
+ - vertices: p0(v8) p2(v7) p1(v3) p3(v0)
+ - neighboring facets: f3 f8 f14 f4
- ridges:
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- - r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
- - r6 tested
- vertices: p6(v6) p4(v0)
- between f13 and f3
- - r10 tested
- vertices: p6(v6) p2(v2)
- between f3 and f8
-- f11
- - flags: top tested seen coplanar
+ - r3 tested
+ vertices: p1(v3) p3(v0)
+ between f3 and f12
+ - r17 tested
+ vertices: p0(v8) p1(v3)
+ between f4 and f12
+ - r19 tested
+ vertices: p0(v8) p2(v7)
+ between f12 and f14
+ - r13 tested
+ vertices: p2(v7) p3(v0)
+ between f12 and f8
+- f8
+ - flags: bottom tested seen coplanar
- merges: 1
- - normal: 0.256313 -0.964458 -0.0642208
+ - normal: -0.768172 -0.218356 -0.601857
- offset: -0.5
- - center: 0.128156 -0.482229 -0.0321104
- - vertices: p7(v8) p5(v7) p1(v5) p3(v1)
- - neighboring facets: f4 f8 f6 f13
+ - center: -0.384086 -0.109178 -0.300928
+ - vertices: p2(v7) p7(v6) p6(v5) p3(v0)
+ - neighboring facets: f7 f3 f12 f14
- ridges:
- - r1 tested
- vertices: p1(v5) p3(v1)
- between f11 and f4
- - r16 tested
- vertices: p7(v8) p3(v1)
- between f8 and f11
- - r19 tested
- vertices: p7(v8) p5(v7)
- between f11 and f13
+ - r10 tested
+ vertices: p7(v6) p6(v5)
+ between f7 and f8
+ - r6 tested
+ vertices: p7(v6) p3(v0)
+ between f8 and f3
+ - r13 tested
+ vertices: p2(v7) p3(v0)
+ between f12 and f8
- r14 tested
- vertices: p5(v7) p1(v5)
- between f11 and f6
-- f6
- - flags: bottom tested seen coplanar
+ vertices: p2(v7) p6(v5)
+ between f8 and f14
+- f7
+ - flags: bottom tested seen
- merges: 1
- - normal: -0.65396 -0.221954 0.723238
+ - normal: 0.393839 0.579989 -0.713094
- offset: -0.5
- - center: -0.32698 -0.110977 0.361619
- - vertices: p5(v7) p1(v5) p0(v3) p4(v0)
- - neighboring facets: f3 f4 f13 f11
+ - center: 0.19692 0.289994 -0.356547
+ - vertices: p7(v6) p6(v5) p5(v2) p4(v1)
+ - neighboring facets: f4 f14 f3 f8
- ridges:
- r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
- - r14 tested
- vertices: p5(v7) p1(v5)
- between f11 and f6
- - r13 tested
- vertices: p5(v7) p4(v0)
- between f6 and f13
+ vertices: p6(v5) p4(v1)
+ between f7 and f14
- r11 tested
- vertices: p0(v3) p4(v0)
- between f3 and f6
+ vertices: p5(v2) p4(v1)
+ between f4 and f7
+ - r7 tested
+ vertices: p7(v6) p5(v2)
+ between f3 and f7
+ - r10 tested
+ vertices: p7(v6) p6(v5)
+ between f7 and f8
INFO: Ridges for a facet
- - r4 tested
- vertices: p0(v3) p2(v2)
- between f4 and f3
- r3 tested
- vertices: p2(v2) p3(v1)
- between f4 and f8
- - r1 tested
- vertices: p1(v5) p3(v1)
- between f11 and f4
- - r2 tested
- vertices: p1(v5) p0(v3)
- between f4 and f6
+ vertices: p1(v3) p3(v0)
+ between f3 and f12
+ - r8 tested
+ vertices: p1(v3) p5(v2)
+ between f4 and f3
+ - r6 tested
+ vertices: p7(v6) p3(v0)
+ between f8 and f3
+ - r7 tested
+ vertices: p7(v6) p5(v2)
+ between f3 and f7
PASS : orgQhull::QhullSet_test::t_io()
PASS : orgQhull::QhullSet_test::cleanupTestCase()
Totals: 10 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullSet_test *********
********* Start testing of orgQhull::QhullVertex_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::QhullVertex_test::initTestCase()
PASS : orgQhull::QhullVertex_test::t_constructConvert()
-5
+6
3
+0
2
+5
1
-6
-0
7
8
-XFAIL : orgQhull::QhullVertex_test::t_getSet() ListIterator copy constructor not reset to BOT
-..\..\src\qhulltest\QhullVertex_test.cpp(107) : failure location
-Point 1:
-p1: 0.15707 -0.521517 0.673312
-
-Point 0:
-p0: -0.0992431 0.442941 0.737533
+Point 7:
+ -0.439556 0.573223 -0.477709
-Point 2:
-p2: 0.554717 0.664895 0.0142947
+Point 1:
+ -0.0652231 0.211591 0.837243
Point 3:
-p3: 0.81103 -0.299563 -0.0499261
+ -0.833395 -0.00676534 0.235386
+
+Point 5:
+ 0.328616 0.79158 0.124148
Point 6:
-p6: -0.15707 0.521517 -0.673312
+ 0.0652231 -0.211591 -0.837243
Point 4:
-p4: -0.81103 0.299563 0.0499261
+ 0.833395 0.00676534 -0.235386
-Point 5:
-p5: -0.554717 -0.664895 -0.0142947
+Point 2:
+ -0.328616 -0.79158 -0.124148
-Point 7:
-p7: 0.0992431 -0.442941 -0.737533
+Point 0:
+ 0.439556 -0.573223 0.477709
PASS : orgQhull::QhullVertex_test::t_getSet()
PASS : orgQhull::QhullVertex_test::t_foreach()
-Vertex and vertices w/o runId:
+Vertex and vertices:
- p4 (v1): 0.5 -0.5 -0.5
neighborFacets: f1 f2 f9
p6(v6) p2(v2) p4(v1) p0(v0)
-Vertex and vertices w/ runId:
-- p4 (v1): 0.5 -0.5 -0.5
+
+Vertex and vertices with message:
+Vertex p4 (v1): 0.5 -0.5 -0.5
neighborFacets: f1 f2 f9
-vertices: p6(v6) p2(v2) p4(v1) p0(v0)
+
+Vertices: p6(v6) p2(v2) p4(v1) p0(v0)
Try again with simplicial facets. No neighboring facets listed for vertices.
-Vertex and vertices w/o runId:
+Vertex and vertices:
- p0 (v5): -0.0222149 -0.366435 0.327062
This time with neighborFacets() defined for all vertices:
- p0 (v5): -0.0222149 -0.366435 0.327062
neighborFacets: f5 f6 f7 f8
Try again with Voronoi diagram of simplicial facets. Neighboring facets automatically defined for vertices.
-Vertex and vertices w/o runId:
+Vertex and vertices:
- p7 (v1): 0.386746 0.0449288 0.118336 0.165595
neighborFacets: f1 f6 f9 f13 f14 f15 f16 f18 f19 f21
PASS : orgQhull::QhullVertex_test::t_io()
PASS : orgQhull::QhullVertex_test::cleanupTestCase()
Totals: 6 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::QhullVertex_test *********
+********* Start testing of orgQhull::QhullVertexSet_test *********
+Config: Using QTest library 4.7.4, Qt 4.7.4
+PASS : orgQhull::QhullVertexSet_test::initTestCase()
+INFO : Cube rotated by QR1440989063
+PASS : orgQhull::QhullVertexSet_test::t_construct()
+INFO : Cube rotated by QR1440989063
+PASS : orgQhull::QhullVertexSet_test::t_convert()
+PASS : orgQhull::QhullVertexSet_test::t_readonly()
+INFO : Cube rotated by QR1440989063
+PASS : orgQhull::QhullVertexSet_test::t_foreach()
+INFO : Cube rotated by QR1440989063
+Vertices of first facet with point 0 p7(v6) p1(v3) p5(v2) p3(v0)
+
+Vertex identifiers: v6 v3 v2 v0
+PASS : orgQhull::QhullVertexSet_test::t_io()
+PASS : orgQhull::QhullVertexSet_test::cleanupTestCase()
+Totals: 7 passed, 0 failed, 0 skipped
+********* Finished testing of orgQhull::QhullVertexSet_test *********
********* Start testing of orgQhull::RboxPoints_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::RboxPoints_test::initTestCase()
PASS : orgQhull::RboxPoints_test::t_construct()
INFO : Caught QH6189 rbox error: dimension, D0, out of bounds (>=200 or <=0)
INFO : Caught QH10062 Qhull error: can not set PointCoordinates dimension to -1
PASS : orgQhull::RboxPoints_test::t_error()
PASS : orgQhull::RboxPoints_test::t_test()
INFO : Caught QH10063 Qhull error: can not change PointCoordinates dimension (from 2 to 102)
PASS : orgQhull::RboxPoints_test::t_getSet()
PASS : orgQhull::RboxPoints_test::t_foreach()
INFO : Caught QH10012 Qhull error: expected 4 2-d PointCoordinates but read 3 PointCoordinates plus 1 extra coordinates
PASS : orgQhull::RboxPoints_test::t_change()
PASS : orgQhull::RboxPoints_test::t_ostream()
PASS : orgQhull::RboxPoints_test::cleanupTestCase()
Totals: 9 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::RboxPoints_test *********
-********* Start testing of orgQhull::UsingLibQhull_test *********
-Config: Using QTest library 4.7.4, Qt 4.7.4
-PASS : orgQhull::UsingLibQhull_test::initTestCase()
-MachineEpsilon 2.22045e-016 angleEpsilon 8.9706e-015 distanceEpsilon 9.87561e-015
- Global angleEpsilon 1 distanceEpsilon 1
-INFO Caught error -- QH10057 Qhull error: missing definition for currentVertexDimension(). Need currentQhull() or setGlobalVertexDimension()
-
-PASS : orgQhull::UsingLibQhull_test::t_classMembers()
-pointsBegin 003E9ED0 pointsEnd 003EA010 dimension 4
-INFO Caught error -- QH10059 Qhull error: missing definition for currentPoints(). Need currentQhull() or setGlobalDistanceEpsilon()
-
-PASS : orgQhull::UsingLibQhull_test::t_globalPoints()
-INFO : Caught QH10049 Qhull error: UsingLibQhull already in use by QhullQh.runId 330525930
-PASS : orgQhull::UsingLibQhull_test::t_UsingLibQhull()
-INFO : Caught QH1
-INFO : QH10054 Report previous NOthrow error
-
-Qhull output at end
-qhull: no message for error. Check cerr or error stream
-PASS : orgQhull::UsingLibQhull_test::t_methods()
-PASS : orgQhull::UsingLibQhull_test::t_cleanuptestcase()
-PASS : orgQhull::UsingLibQhull_test::cleanupTestCase()
-Totals: 7 passed, 0 failed, 0 skipped
-********* Finished testing of orgQhull::UsingLibQhull_test *********
********* Start testing of orgQhull::Qhull_test *********
Config: Using QTest library 4.7.4, Qt 4.7.4
PASS : orgQhull::Qhull_test::initTestCase()
INFO : Caught QH10023 Qhull error: checkIfQhullInitialized failed. Call runQhull() first.
-INFO : Caught QH10069 Qhull error: can not use Qhull copy constructor if initialized() is true
-INFO : Caught QH10070 Qhull error: can not use Qhull copy assignment if initialized() is true
-INFO : Caught QH10070 Qhull error: can not use Qhull copy assignment if initialized() is true
PASS : orgQhull::Qhull_test::t_construct()
-Expecting summary of halfspace intersect
+Expecting summary of halfspace intersection
Halfspace intersection by the convex hull of 4 points in 2-d:
Number of halfspaces: 4
Number of non-redundant halfspaces: 4
Number of intersection points: 4
Statistics for: normals of square | qhull H
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 4
CPU seconds to compute hull (after input): 0
Expecting no output from qh_fprintf() in Qhull.cpp
Qhull output at end
Halfspace intersection by the convex hull of 4 points in 2-d:
Number of halfspaces: 4
Number of non-redundant halfspaces: 4
Number of intersection points: 4
Statistics for: normals of square | qhull H
Number of points processed: 4
Number of hyperplanes created: 6
Number of distance tests for qhull: 4
CPU seconds to compute hull (after input): 0
PASS : orgQhull::Qhull_test::t_attribute()
INFO : Caught QH6029 qhull error: option 'Fd' is not used with this program.
It may be used with qhull.
While executing: |
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 330525930
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1530094622
INFO : Error stream without output stream
qhull error: option 'Fd' is not used with this program.
It may be used with qhull.
While executing: |
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 330525930
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1530094622
INFO : Caught QH6029
INFO : Error output sent to output stream without error stream
qhull input error: feasible point is not clearly inside halfspace
feasible point: 0 0
halfspace: -0.5 -0.5
at offset: 0.5 and distance: 0.5
The halfspace was at index 1
While executing: rbox "c" | qhull Tz H0
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 330525930 Tz-stdout Halfspace-about 0
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1530094622 Tz-stdout Halfspace-about 0
INFO : Caught QH6023
INFO : No error stream or output stream
INFO : Caught QH6029 qhull error: option 'Fd' is not used with this program.
It may be used with qhull.
While executing: |
-Options selected for Qhull 2012.1 2012/01/22:
- run-id 330525930
+Options selected for Qhull 2015.0.2.r 2015/08/30:
+ run-id 1530094622
PASS : orgQhull::Qhull_test::t_message()
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
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 84
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
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
Number of points processed: 8
Number of hyperplanes created: 11
Number of distance tests for qhull: 35
Number of distance tests for merging: 84
Number of distance tests for checking: 56
Number of merged facets: 6
CPU seconds to compute hull (after input): 0
PASS : orgQhull::Qhull_test::t_getSet()
PASS : orgQhull::Qhull_test::t_getQh()
PASS : orgQhull::Qhull_test::t_getValue()
PASS : orgQhull::Qhull_test::t_foreach()
Expecting vertexList and facetList of a 3-d diamond.
3
6 8 12
0 0 -0.5
0 0 0.5
0 -0.5 0
0 0.5 0
-0.5 0 0
0.5 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
Expecting normals of a 3-d diamond.
4
8
-0.5773502691896258 0.5773502691896258 0.5773502691896258 -0.2886751345948129
0.5773502691896258 0.5773502691896258 0.5773502691896258 -0.2886751345948129
-0.5773502691896258 0.5773502691896258 -0.5773502691896258 -0.2886751345948129
0.5773502691896258 0.5773502691896258 -0.5773502691896258 -0.2886751345948129
0.5773502691896258 -0.5773502691896258 0.5773502691896258 -0.2886751345948129
-0.5773502691896258 -0.5773502691896258 0.5773502691896258 -0.2886751345948129
-0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.2886751345948129
0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.2886751345948129
PASS : orgQhull::Qhull_test::t_modify()
PASS : orgQhull::Qhull_test::cleanupTestCase()
Totals: 10 passed, 0 failed, 0 skipped
********* Finished testing of orgQhull::Qhull_test *********
-Passed 121 tests.
-Finished test of libqhullcpp. Test libqhull with eg/q_test
+Passed 128 tests.
+Finished test of libqhullcpp. Test libqhull_r with eg/q_test after building libqhull_r/Makefile
diff --git a/html/qh-code.htm b/html/qh-code.htm
index f8326c5..c193761 100644
--- a/html/qh-code.htm
+++ b/html/qh-code.htm
@@ -1,954 +1,948 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Qhull code</title>
<!-- Navigation links -->
</head>
<body>
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page for Qhull</a>
<br>
<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of
Contents</a><br>
<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
&#149; <a href="qh-quick.htm#options">Options</a>
&#149; <a href="qh-opto.htm#output">Output</a>
&#149; <a href="qh-optf.htm#format">Formats</a>
&#149; <a href="qh-optg.htm#geomview">Geomview</a>
&#149; <a href="qh-optp.htm#print">Print</a>
&#149; <a href="qh-optq.htm#qhull">Qhull</a>
&#149; <a href="qh-optc.htm#prec">Precision</a>
&#149; <a href="qh-optt.htm#trace">Trace</a><br>
<b>To:</b> <a href="#TOC">Qhull code</a>: Table of Contents
(please wait while loading) <br>
<b>Dn:</b> <a href="../src/libqhull/index.htm">Qhull functions</a>, macros, and data
structures
</p>
<hr>
<!-- Main text of document -->
<h1><a
href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/4dcube.html"><img
src="qh--4d.gif" alt="[4-d cube]" align="middle" width="100"
height="100"></a> Qhull code</h1>
<p>This section discusses the code for Qhull. </p>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull code: Table of
Contents </a></h2>
<ul>
- <li><a href="#performance">Performance</a> of Qhull</li>
+ <li><a href="#reentrant">Reentrant Qhull</a>
+ <li><a href="#64bit">Qhull on 64-bit hosts</a>
<li><a href="#cpp">Calling Qhull</a> from C++ programs
<ul>
<li><a href="#questions-cpp">Cpp questions for Qhull</a></li>
<li><a href="#coordinate-cpp">CoordinateIterator</a></li>
<li><a href="#qhull-cpp">Qhull</a></li>
<li><a href="#error-cpp">QhullError</a></li>
<li><a href="#facet-cpp">QhullFacet</a></li>
<li><a href="#facetlist-cpp">QhullFacetList</a></li>
<li><a href="#facetset-cpp">QhullFacetSet</a></li>
<li><a href="#iterator-cpp">QhullIterator</a></li>
<li><a href="#linkedlist-cpp">QhullLinkedList</a></li>
<li><a href="#point-cpp">QhullPoint</a></li>
<li><a href="#qh-cpp">QhullQh</a></li>
<li><a href="#pointset-cpp">QhullPointSet</a></li>
<li><a href="#ridge-cpp">QhullRidge</a></li>
<li><a href="#ridgeset-cpp">QhullRidgeSet</a></li>
<li><a href="#set-cpp">QhullSet</a></li>
<li><a href="#vertex-cpp">QhullVertex</a></li>
<li><a href="#vertexlist-cpp">QhullVertexList</a></li>
<li><a href="#vertexset-cpp">QhullVertexSet</a></li>
<li><a href="#rbox-cpp">RboxPoints</a></li>
- <li><a href="#usingqhull-cpp">UsingLibQhull</a></li>
</ul>
<li><a href="#library">Calling Qhull</a> from C programs
<ul>
<li><a href="#constrained">Constrained Delaunay</a>
triangulation</li>
<li><a href="#dids">Delaunay triangulations</a> and point indices</li>
<li><a href="#findfacet">Locate facet</a> with
qh_findbestfacet()</li>
<li><a href="#inc">On-line construction</a> with
qh_addpoint()</li>
<li><a href="#mem">Sets and quick memory</a> allocation</li>
<li><a href="#tricoplanar">Tricoplanar facets</a> and option 'Qt'</li>
<li><a href="#vneighbor">Vertex neighbors</a> of a vertex</li>
<li><a href="#vertices">Voronoi vertices</a> of a region</li>
<li><a href="#ridge">Voronoi vertices</a> of a ridge</li>
</ul>
</li>
+ <li><a href="#performance">Performance</a> of Qhull</li>
<li><a href="#enhance">Enhancements</a> to Qhull</li>
<li><a href="../src/libqhull/index.htm">Qhull functions</a>, macros, and data
structures </li>
</ul>
<hr>
-<h2><a href="#TOC">&#187;</a><a name="performance">Performance of
-Qhull </a></h2>
-
-<p>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 <i>O(log n)</i>
-bits. Empirically, the maximum number of vertices occurs at the
-end of constructing the hull. </p>
-
-<p>Let <i>n</i> be the number of input points, <i>v</i> be the
-number of output vertices, and <i>f_v </i>be the maximum number
-of facets for a convex hull of <i>v</i> vertices. If both
-conditions hold, Qhull runs in <i>O(n log v)</i> in 2-d and 3-d
-and <i>O(n f_v/v)</i> otherwise. The function <i>f_v</i>
-increases rapidly with dimension. It is <em>O(v^floor(d/2) /
-floor(d/2)!)</em>.</p>
-
-<p>The time complexity for merging is unknown. Options '<a
-href="qh-optc.htm#C0">C-0</a>' and '<a href="qh-optq.htm#Qx">Qx</a>'
-(defaults) handle precision problems due to floating-point
-arithmetic. They are optimized for simplicial outputs. </p>
-
-<p>When running large data sets, you should monitor Qhull's
-performance with the '<a href="qh-optt.htm#TFn">TFn</a>' 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. </p>
-
-<p>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. </p>
-
-<p>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. </p>
-
-<p>When building hulls in 20-d and higher, you can follow the
-progress of Qhull with option '<a href="qh-optt.htm#Tn">T1</a>'.
-It reports each major event in processing a point. </p>
+<h2><a href="#TOC">&#187;</a><a name="reentrant">Reentrant Qhull</a></h2>
-<p>To reduce memory requirements, recompile Qhull for
-single-precision reals (REALfloat in <tt>user.h</tt>).
-Single-precision does not work with joggle ('<a
-href="qh-optq.htm#QJn">QJ</a>'). Check qh_MEMalign in <tt>user.h</tt>
-and the match between free list sizes and data structure sizes
-(see the end of the statistics report from '<a
-href="qh-optt.htm#Ts">Ts</a>'). 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 <tt>user.h</tt>).</p>
+<p>Qhull-2015 introduces reentrant Qhull (libqhull_r). Reentrant Qhull replaces Qhull's global data structures with a qhT pointer.
+The 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.
-<p>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.</p>
+<p>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.
-<p>To reduce the size of the Qhull executable, consider
-qh_NOtrace and qh_KEEPstatistics 0 in <tt>user.h</tt>. By
-changing <tt>user.c </tt>you can also remove the input/output
-code in <tt>io.c</tt>. 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.</p>
-
-<p>The precision options, '<a href="qh-optc.htm#Vn">Vn</a>', '<a
-href="qh-optc.htm#Wn">Wn</a>', '<a href="qh-optc.htm#Un">Un</a>'.
-'<a href="qh-optc.htm#An">A-n</a>', '<a href="qh-optc.htm#Cn">C-n</a>',
-'<a href="qh-optc.htm#An2">An</a>', '<a href="qh-optc.htm#Cn2">Cn</a>',
-and '<a href="qh-optq.htm#Qx">Qx</a>', may have large effects on
-Qhull performance. You will need to experiment to find the best
-combination for your application. </p>
-
-<p>The verify option ('<a href="qh-optt.htm#Tv">Tv</a>') 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.</p>
+<p>C++ users need to convert to libqhull_r. The previous C++ interface was unusual
+due to Qhull's global data structures (e.g., UsingLibQhull.cpp).
+The new C++ interface does a better, but not perfect, job of hiding Qhull's C data structures.
-<p>The check-frequently option ('<a href="qh-optt.htm#Tc">Tc</a>')
-becomes expensive as the dimension increases. The verify option
-('<a href="qh-optt.htm#Tv">Tv</a>') performs many of the same
-checks before outputting the results.</p>
+<b>Note:</b> Reentrant Qhull is <i>not</i> thread safe. Do not invoke Qhull routines with the same qhT pointer from multiple threads.
-<p>Options '<a href="qh-optq.htm#Q0">Q0</a>' (no pre-merging), '<a
-href="qh-optq.htm#Q3">Q3</a>' (no checks for redundant vertices),
-'<a href="qh-optq.htm#Q5">Q5</a>' (no updates for outer planes),
-and '<a href="qh-optq.htm#Q8">Q8</a>' (no near-interior points)
-increase Qhull's speed. The corresponding operations may not be
-needed in your application.</p>
+<h2><a href="#TOC">&#187;</a><a name="64bit">Qhull on 64-bit hosts</a></h2>
-<p>In 2-d and 3-d, a partial hull may be faster to produce.
-Option '<a href="qh-optq.htm#QGn">QgGn</a>' only builds facets
-visible to point n. Option '<a href="qh-optq.htm#QVn">QgVn</a>'
-only builds facets that contain point n. In higher-dimensions,
-this does not reduce the number of facets.</p>
+<p>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 <a href="qh-optt.htm#Ts">Ts</a>.
-<p><tt>User.h</tt> 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. </p>
+<p>A custom version of Qhull for 3-D Delaunay triangulations may reduce space requirements substantially.
-<p>GNU <tt>gprof</tt> 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.
+<p>On 64-bit hosts, reentrant qhull is nearly as fast as non-reentrant qhull.
-</p>
<h2><a href="#TOC">&#187;</a><a name="cpp">Calling Qhull from
C++ programs</a></h2>
-<p><b>Warning:</b> The C++ interface to Qhull is new and
-incomplete. You will need to extend the interface for all
-but the simplest applications.
-You will need to understand the data structures and read the code.
-Most users will find it easier to call Qhull as a program.
-
-<p><b>Note:</b> Please download the 'next' branch from
-git://gitorious.org/qhull/qhull.git
+<p>Qhull 2015 uses reentrant Qhull for its C++ interface. If you used
+the C++ interface from qhull 2012.1, you will need to adjust how you initialize and use
+the Qhull classes. See <a href="../src/Changes.txt">Changes.txt</a> for details.
<p>
-Qhull's C++ interface provides wrapper classes for Qhull and Rbox. It provides access to Qhull's data structures.
+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, <a href="#facet-cpp">QhullFacet</a> is an instance of Qhull's <a href="../src/libqhull/libqhull.h#facetT">facetT</a>.
+Each object contains a reference the Qhull's data structure (via QhullQh), making the C++ representation less memory efficient.
+You should retain most of the data in Qhull and use the C++ interface to explore its results.
</p>
-The main methods are
-<ul><li>
- <code>RboxPoints.appendRandomPoints</code> -- append random points according to rbox options.
- </li><li>
- <code>Qhull.runQhull</code> -- construct the convex hull of the input points
- </li><li>
- <code>Qhull.outputQhull</code> -- write output according to Qhull options
-</li></ul>
+<p>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.
-The sample program,
-<a href=../src/user_eg3/user_eg3.cpp>user_eg3.cpp</a>, duplicates Qhull's facet dump (option 'f').
+Example (c.f., <code>user_eg3 eg-100</code>). It prints the facets generated by Qhull.
-Example (c.f., <code>user_eg3 eg-100</code>)
<pre>
RboxPoints rbox;
rbox.appendRandomPoints("100");
Qhull qhull;
qhull.runQhull("", rbox);
QhullFacetList facets(qhull);
cout<< facets;
</pre>
<p>
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++.
</p>
<ul><li>
Run Qhull with option '<a href="qh-optt.htm#Ta">Ta</a>' to annotate the
output with qh_fprintf() identifiers.
</li><li>
Redefine qh_fprintf() for these identifiers.
</li><li>
See RboxPoints.cpp for an example.
</li></ul>
<p>
A more flexible approach extends Qhull's classes. For example,
to access the vertices of a <a href="#facet-cpp">QhullFacet</a>,
define a constructor of <a href="#vertexset-cpp">QhullVertexSet</a>
that takes a QhullFacet as a parameter.
</p>
<p>
-With care, you may create multiple Qhull instances, but only one thread may use qh_qh,
-qh_qhstat, and qhmem at a time (i.e., most of libqhull, the original C program).
-only one instance may be active at time. The global pointer <code>qh_qh</code>
-points to Qhull's data structure, <a href="#qh-cpp">QhullQh</a>. The class
-<a href="#usingqhull-cpp">UsingLibQhull</a> checks that qh_qh is correct.
+Since the C++ interface uses reentrant Qhull, multiple threads may run Qhull at the same time. Each thread is
+one run of Qhull. Do <i>not</i> have two threads accessing the same Qhull instance.
</p>
-<p>
-Qhull objects have the entire qhull data structure, so they can explore this data structure independent of
-libqhull. You can use any method that does not refer to UsingLibQhull, or invoke methods that refer to UsingLibQhull.
-You may also use any method in libqhull that does not reference qh_qh, qh_qhstat (i.e., does not include the macro 'qh',
-zinc_, etc) and does not allocate or deallocate memory via mem.c.
-In particular, you can call most of the qset macros and functions, allowing you to explore the data structure
-with 'foreachFacet_(), etc.' You can call all of the qset.h functions if you turn off Qhull's memory manager (qh_NOmem in mem.h)
-</p>
-
-<h3><a href="#TOC">&#187;</a><a name="questions-cpp">Cpp questions for Qhull</a></h3>
-
-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
-<a href="http://www.qhull.org/road/road-faq/xml/cpp-guideline.xml">C++ and Perl Guidelines</a>,
-<a href="http://www.qhull.org/road/road-faq/xml/qhull-cpp.xml">C++ interface to Qhull</a>. and FIXUP
-in the code. Please add notes to <a href="http://gitorious.org/qhull/pages/Home">Gitorious wiki</a>.
-
-<ul>
-<li>FIXUP QH11026 Should return reference, but get reference to temporary
-<pre>iterator Coordinates::operator++() { return iterator(++i); }</pre>
-<li>size() as size_t, size_type, or int
-<li>Should all containers have a reserve()?
-<li>Qhull.feasiblePoint interface
-<li>How to avoid copy constructor while logging, maybeThrowQhullMessage()
-<li>How to configure Qhull output. Trace and results should go to stdout/stderr
-<li>Qhull and RboxPoints messaging. e.g., ~Qhull, hasQhullMessage(). Rename them as QhullErrorMessage?
-<li>How to add additional output to an error message, e.g., qh_setprint
-<li>Is idx the best name for an index? It's rather cryptic, but BSD strings.h defines index().
-<li>Qhull::feasiblePoint Qhull::useOutputStream as field or getter?
-<li>Define virtual functions for user customization of Qhull (e.g., qh_fprintf, qh_memfree,etc.)
-<li>Figure out RoadError::global_log. clearQhullMessage currently clearGlobalLog
-<li>Should the false QhullFacet be NULL or empty? e.g., QhullFacet::tricoplanarOwner() and QhullFacetSet::end()
-<li>Should output format for floats be predefined (qh_REAL_1, 2.2g, 10.7g) or as currently set for stream
-<li>Should cout << !point.defined() be blank or 'undefined'
-<li>Interface for UsingLibQhull::globalAngleEpsilon(), globalDistanceEpsilon, etc.
-<li>Interface for UsingLibQhull::globalDimension
-<li>Set up globals for thread-private storage (redefine macros qh, qhstat, etc)
-<li>Is Q_GLOBAL_STATIC non-threaded/threaded, needed for Qhull?
-<li>Infinite point as !defined()
-<li>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 -- <pre>reference operator[](difference_type _Off) const</pre>
-<li>When forwarding an implementation is base() an approriate name (e.g., Coordinates::iterator::base() as std::vector<coordT>::iterator).
-<li>When forwarding an implementation, does not work "returning address of temporary"
-<li>Also --, +=, and -=
- <pre>iterator &operator++() { return iterator(i++); }</pre>
-<li>if vector<coordT> inheritance is bad, is QhullVertexSet OK?
-<li>Should QhullPointSet define pointer and reference data types?
-<li>Allow UsingQhullLib to work with static allocation of qh_qh
-</ul>
-
<h3><a href="#TOC">&#187;</a><a name="coordinate-cpp">CoordinateIterator</a></h3>
<p>
A CoordinateIterator or ConstCoordinateIterator [RboxPoints.cpp] is a <code>std::vector&lt;realT>::iterator</code> for Rbox and Qhull coordinates.
It is the result type of <a href="#rbox-cpp">RboxPoints</a>.coordinates().
</p>
<p>Qhull does not use CoordinateIterator for its data structures. A point in Qhull is an array of reals instead of a std::vector.
See <a href="#point-cpp">QhullPoint</a>.
</p>
<h3><a href="#TOC">&#187;</a><a name="qhull-cpp">Qhull</a></h3>
<p>
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 <a href="#qh-cpp">QhullQh</a>,
Qhull's <a href="#facet-cpp">facets</a>, and <a href="#vertex-cpp">vertices</a>.
</p>
<h3><a href="#TOC">&#187;</a><a name="error-cpp">QhullError</a></h3>
<p>
QhullError is derived from <code>std::exception</code>. It reports errors from Qhull and captures the output to stderr.
</p>
<p>
If error handling is not set up, Qhull exits with a code from 1 to 5
[qh_ERR* in libqhull.h via qh_exit() in usermem.c]. The C++ interface does not report the
captured output in QhullError. Call Qhull::setErrorStream to send output to cerr instead.
</p>
<h3><a href="#TOC">&#187;</a><a name="facet-cpp">QhullFacet</a></h3>
<p>
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 <a href="#vertex-cpp">QhullVertex</a>, a set of <a href="#ridge-cpp">QhullRidge</a>, and
a set of neighboring QhullFacets.
</p>
<h3><a href="#TOC">&#187;</a><a name="facetlist-cpp">QhullFacetList</a></h3>
<p>
A QhullFacetList is a linked list of <a href="#facet-cpp">QhullFacet</a>. The result of <code>Qhull.runQhull</code> is a QhullFacetList stored
in <a href="#qh-cpp">QhullQh</a>.
</p>
<h3><a href="#TOC">&#187;</a><a name="facetset-cpp">QhullFacetSet</a></h3>
<p>
A QhullFacetSet is a <a href="#set-cpp">QhullSet</a> of <a href="#facet-cpp">QhullFacet</a>. QhullFacetSet may be ordered or unordered. The neighboring facets of a QhullFacet is a QhullFacetSet.
The neighbors of a <a href="#facet-cpp">QhullFacet</a> is a QhullFacetSet.
The neighbors are ordered for simplicial facets, matching the opposite vertex of the facet.
</p>
<h3><a href="#TOC">&#187;</a><a name="iterator-cpp">QhullIterator</a></h3>
<p>
QhullIterator contains macros for defining Java-style iterator templates from a STL-style iterator template.
</p>
<h3><a href="#TOC">&#187;</a><a name="linkedlist-cpp">QhullLinkedList</a></h3>
<p>
A QhullLinkedLIst is a template for linked lists with next and previous pointers.
<a href="#facetlist-cpp">QhullFacetList</a> and <a href="#facetlist-cpp">QhullVertexList</a> are QhullLinkedLists.
</p>
<h3><a href="#TOC">&#187;</a><a name="point-cpp">QhullPoint</a></h3>
<p>
A QhullPoint is an array of point coordinates, typically doubles. The length of the array is <a href="#qh-cpp">QhullQh</a>.hull_dim.
The identifier of a QhullPoint is its 0-based index from QhullQh.first_point followed by QhullQh.other_points.
</p>
<h3><a href="#TOC">&#187;</a><a name="pointset-cpp">QhullPointSet</a></h3>
<p>
A QhullPointSet is a <a href="#set-cpp">QhullSet</a> of <a href="#point-cpp">QhullPoint</a>. The QhullPointSet of a <a href="#facet-cpp">QhullFacet</a> is its coplanar points.
</p>
<h3><a href="#TOC">&#187;</a><a name="qh-cpp">QhullQh</a></h3>
<p>
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 <a href="#point-cpp">QhullPoint</a>,
a list of <a href="#facet-cpp">QhullFacet</a>, and a list of <a href="#vertex-cpp">QhullVertex</a>.
The points are the input to Qhull. The facets and vertices are the result of running Qhull.
</p>
<p>
Qhull's functions access QhullQh through the global variable, <code>qh_qh</code>.
The global data structures, qh_stat and qh_mem, record statistics and manage memory respectively.
</p>
<h3><a href="#TOC">&#187;</a><a name="ridge-cpp">QhullRidge</a></h3>
<p>
A QhullRidge represents the edge between two <a href="#facet-cpp">QhullFacet</a>'s.
It is always simplicial with qh.hull_dim-1 <a href="#vertex-cpp">QhullVertex</a>)'s.
</p>
<h3><a href="#TOC">&#187;</a><a name="ridgeset-cpp">QhullRidgeSet</a></h3>
<p>
A QhullRidgeSet is a <a href="#set-cpp">QhullSet</a> of <a href="#ridge-cpp">QhullRidge</a>. Each <a href="#facet-cpp">QhullFacet</a> contains a QhullRidgeSet.
</p>
<h3><a href="#TOC">&#187;</a><a name="set-cpp">QhullSet</a></h3>
<p>
A QhullSet is a set of pointers to objects. QhullSets may be ordered or unordered. They are the core data structure for Qhull.
</p>
<h3><a href="#TOC">&#187;</a><a name="vertex-cpp">QhullVertex</a></h3>
<p>
A QhullVertex is a vertex of the convex hull. A simplicial <a href="#facet-cpp">QhullFacet</a> has qh.hull_dim-1 vertices. A QhullVertex contains a <a href="#point-cpp">QhullPoint</a>.
It may list its neighboring <a href="#facet-cpp">QhullFacet</a>'s.
</p>
<h3><a href="#TOC">&#187;</a><a name="vertexlist-cpp">QhullVertexList</a></h3>
<p>
A QhullVertexList is a <a href="#linkedlist-cpp">QhullLinkedList</a> of <a href="#vertex-cpp">QhullVertex</a>.
The global data structure, <a href="#qh-cpp">QhullQh</a> contains a QhullVertexList of all
the vertices.
</p>
<h3><a href="#TOC">&#187;</a><a name="vertexset-cpp">QhullVertexSet</a></h3>
<p>
A QhullVertexSet is a <a href="#set-cpp">QhullSet</a> of <a href="#vertex-cpp">QhullVertex</a>.
The QhullVertexSet of a <a href="#facet-cpp">QhullFacet</a> is the vertices of the facet. It is
ordered for simplicial facets and unordered for non-simplicial facets.
</p>
<h3><a href="#TOC">&#187;</a><a name="rbox-cpp">RboxPoints</a></h3>
<p>
RboxPoints is a std::vector of point coordinates (<a href="#point-cpp">QhullPoint</a>).
It's iterator is <a href="#coordinate-cpp">CoordinateIterator</a>.
</p>
<p>
<code>RboxPoints.appendRandomPoints()</code> 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.
</p>
-<h3><a href="#TOC">&#187;</a><a name="usingqhull-cpp">UsingLibQhull</a></h3>
+<h3><a href="#TOC">&#187;</a><a name="questions-cpp">Cpp questions for Qhull</a></h3>
-<p>
-UsingLibQhull checks that the current thread owns Qhull's global data structure, <a href="#qh-cpp">QhullQh</a>.
-It is required while calling the Qhull library. Otherwise two threads may be updating and reading the same data structure.
-</p>
+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
+<a href="http://www.qhull.org/road/road-faq/xml/cpp-guideline.xml">C++ and Perl Guidelines</a>.
+and FIXUP notes in the code.
+Please add notes to <a href="http://gitorious.org/qhull/pages/Home">Gitorious wiki</a>.
+
+<ul>
+<li>FIXUP QH11026 Should return reference, but get reference to temporary
+<pre>iterator Coordinates::operator++() { return iterator(++i); }</pre>
+<li>size() as size_t, size_type, or int
+<li>Should all containers have a reserve()?
+<li>Qhull.feasiblePoint interface
+<li>How to avoid copy constructor while logging, maybeThrowQhullMessage()
+<li>How to configure Qhull output. Trace and results should go to stdout/stderr
+<li>Qhull and RboxPoints messaging. e.g., ~Qhull, hasQhullMessage(). Rename them as QhullErrorMessage?
+<li>How to add additional output to an error message, e.g., qh_setprint
+<li>Is idx the best name for an index? It's rather cryptic, but BSD strings.h defines index().
+<li>Qhull::feasiblePoint Qhull::useOutputStream as field or getter?
+<li>Define virtual functions for user customization of Qhull (e.g., qh_fprintf, qh_memfree,etc.)
+<li>Figure out RoadError::global_log. clearQhullMessage currently clearGlobalLog
+<li>Should the false QhullFacet be NULL or empty? e.g., QhullFacet::tricoplanarOwner() and QhullFacetSet::end()
+<li>Should output format for floats be predefined (qh_REAL_1, 2.2g, 10.7g) or as currently set for stream
+<li>Should cout << !point.defined() be blank or 'undefined'
+<li>Infinite point as !defined()
+<li>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 -- <pre>reference operator[](difference_type _Off) const</pre>
+<li>When forwarding an implementation is base() an approriate name (e.g., Coordinates::iterator::base() as std::vector<coordT>::iterator).
+<li>When forwarding an implementation, does not work "returning address of temporary"
+<li>Also --, +=, and -=
+ <pre>iterator &operator++() { return iterator(i++); }</pre>
+<li>if vector<coordT> inheritance is bad, is QhullVertexSet OK?
+<li>Should QhullPointSet define pointer and reference data types?
+</ul>
<h2><a href="#TOC">&#187;</a><a name="library">Calling Qhull from
C programs</a></h2>
<p><b>Warning:</b> Qhull was not designed for calling from C
programs. You may find the <a href="#cpp">C++ interface</a> 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.
<p>For examples of calling Qhull, see GNU Octave's
<a href=http://www.gnu.org/software/octave/doc/interpreter/Geometry.html>computational geometry code</a>,
and Qhull's
-<a href=../src/user_eg/user_eg.c>user_eg.c</a>,
-<a href=../src/user_eg2/user_eg2.c>user_eg2.c</a>, and
-<a href=../src/libqhull/user.c>user.c</a>. To see how Qhull calls its library, read
-<a href=../src/qhull/unix.c>unix.c</a>,
+<a href=../src/user_eg/user_eg_r.c>user_eg_r.c</a>,
+<a href=../src/user_eg2/user_eg2_r.c>user_eg2_r.c</a>, and
+<a href=../src/libqhull_r/user_r.c>user_r.c</a>. To see how Qhull calls its library, read
+<a href=../src/qhull/unix_r.c>unix_r.c</a>,
<a href=../src/qconvex/qconvex.c>qconvex.c</a>,
<a href=../src/qdelaunay/qdelaun.c>qdelaun.c</a>,
<a href=../src/qhalf/qhalf.c>qhalf.c</a>, and
-<a href=../src/qvoronoi/qvoronoi.c>qvoronoi.c</a>.
+<a href=../src/qvoronoi/qvoronoi.c>qvoronoi.c</a>. The '*_r.c' files are reentrant, otherwise they are non-reentrant.
+Either version may be used. New code should use reentrant Qhull.
<p>The <a href=http://www.boost.org/libs/graph/doc/table_of_contents.html>BGL</a>
Boost Graph Library [aka GGCL] provides C++ classes for graph data structures
and algorithms [Dr. Dobb's 9/00 p. 29-38; OOPSLA '99 p. 399-414]. It is modelled after the
Standard Template Library. It would provide a good interface to Qhull.
If you are interested in adapting BGL to Qhull, please contact
<a href="mailto:bradb@shore.net">bradb@shore.net</a>.
<p>See <a href="../src/libqhull/index.htm">Qhull functions, macros, and data
structures</a> 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.</p>
-<p>When you read the code, be aware of the macros &quot;qh&quot;
+<p>If you use non-reentrant Qhull, be aware of the macros &quot;qh&quot;
and &quot;qhstat&quot;, e.g., &quot;qh hull_dim&quot;. They are
defined in <tt>libqhull.h</tt>. They allow the global data
structures to be pre-allocated (faster access) or dynamically
allocated (allows multiple copies). </p>
-<p>Qhull's <tt>Makefile</tt> produces a library, <tt>libqhull.a</tt>,
-for inclusion in your programs. First review <tt>libqhull.h</tt>.
+<p>Qhull's <tt>Makefile</tt> produces a library, <tt>libqhull_r.a</tt>,
+for inclusion in your programs. First review <tt>libqhull_r.h</tt>.
This defines the data structures used by Qhull and provides
prototypes for the top-level functions.
-Most users will only need libqhull.h in their programs. For
-example, the Qhull program is defined with <tt>libqhull.h</tt> and <tt>unix.c</tt>.
-To access all functions, use <tt>qhull_a.h</tt>. Include the file
-with &quot;<tt>#include &lt;libqhull/qhull_a.h&gt;&quot;.</tt> This
+Most users will only need libqhull_r.h in their programs. For
+example, the Qhull program is defined with <tt>libqhull_r.h</tt> and <tt>unix_r.c</tt>.
+To access all functions, use <tt>qhull_ra.h</tt>. Include the file
+with &quot;<tt>#include &lt;libqhull_r/qhull_ra.h&gt;</tt>&quot;. This
avoids potential name conflicts.</p>
<p>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
'<a href="qh-optt.htm#Tc">Tc</a>' option will catch many problems
as they occur. When an error occurs, use '<a
href="qh-optt.htm#Tn">T4</a> <a href="qh-optt.htm#TPn">TPn</a>'
to trace from the last point added to the hull. Compare your
trace with the trace output from the Qhull program.</p>
<p>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. </p>
<h3><a href="#TOC">&#187;</a><a name="mem">sets and quick memory
allocation</a></h3>
-<p>You can use <tt>mem.c</tt> and<tt> qset.c</tt> individually. <tt>Mem.c
+<p>You can use <tt>mem_r.c</tt> and <tt>qset_r.c</tt> individually. <tt>Mem_r.c
</tt>implements quick-fit memory allocation. It is faster than
malloc/free in applications that allocate and deallocate lots of
memory. </p>
-<p><tt>Qset.c</tt> implements sets and related collections. It's
+<p><tt>Qset_r.c</tt> implements sets and related collections. It's
the inner loop of Qhull, so speed is more important than
-abstraction. Set iteration is particularly fast. <tt>qset.c</tt>
+abstraction. Set iteration is particularly fast. <tt>qset_r.c</tt>
just includes the functions needed for Qhull. </p>
<h3><a href="#TOC">&#187;</a><a name="dids">Delaunay triangulations
and point indices</a></h3>
<p>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. </p>
<blockquote>
<pre>
facetT *facet;
vertexT *vertex, **vertexp;
FORALLfacets {
if (!facet-&gt;upperdelaunay) {
printf (&quot;%d&quot;, qh_setsize (facet-&gt;vertices);
FOREACHvertex_(facet-&gt;vertices)
printf (&quot; %d&quot;, qh_pointid (vertex-&gt;point));
printf (&quot;\n&quot;);
}
}
</pre>
</blockquote>
<h3><a href="#TOC">&#187;</a><a name="findfacet">locate a facet with
qh_findbestfacet()</a></h3>
-<p>The routine qh_findbestfacet in <tt>poly2.c</tt> is
+<p>The routine qh_findbestfacet in <tt>poly2_r.c</tt> 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.</p>
<blockquote>
<p><b>Warning:</b> If triangulated output ('<a href=qh-optq.htm#Qt>Qt</a>') 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.
<p>
See qh_nearvertex() in poly2.c for sample code to visit each
tricoplanar facet. To identify the correct tricoplanar facet,
see Devillers, et. al., [<a href="index.htm#devi01">'01</a>]
and Mucke, et al [<a href="index.htm#muck96">'96</a>]. If you
implement this test in general dimension, please notify
<a href="mailto:qhull@qhull.org">qhull@qhull.org</a>.
</blockquote>
<p>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. </p>
<p>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 <a href="index.htm#dob-kir90">'90</a>]. </p>
<p>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.c). Do not scale the input with
+(see qh_setdelaunay in geom2_r.c). Do not scale the input with
options 'Qbk', 'QBk', 'QbB' or 'Qbb'. See Mucke, et al [<a
href="index.htm#muck96">'96</a>] for a good point location
algorithm.</p>
<p>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. </p>
<h3><a href="#TOC">&#187;</a><a name="inc">on-line construction with
qh_addpoint()</a></h3>
<p>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 <a
href="http://www.netlib.org/voronoi/hull.html">hull
program</a>). 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). </p>
<p>You may use qh_findbestfacet and qh_addpoint (<tt>libqhull.c</tt>) 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 (<a href="#findfacet">qh_findbestfacet</a>).
</p>
<p>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). </p>
<p>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.</p>
<p>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] </p>
<p>See user_eg.c for examples of the on-line construction of
convex hulls, Delaunay triangulations, and halfspace
intersections. The outline is: </p>
<blockquote>
<pre>
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, &amp;bestdist, &amp;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</pre>
</blockquote>
<h3><a href="#TOC">&#187;</a><a name="constrained">Constrained
Delaunay triangulation </a></h3>
<p>With a fair amount of work, Qhull is suitable for constrained
Delaunay triangulation. See Shewchuk, ACM Symposium on
Computational Geometry, Minneapolis 1998.</p>
<p>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] </p>
<h3><A href="#TOC">&#187;</A><a name="tricoplanar">Tricoplanar facets and option 'Qt'</h3>
<p>Option '<a href=qh-optq.htm#Qt>Qt</a>' 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.
<p>Qhull sets facet->degenerate if the facet's vertices belong
to the same ridge of the non-simplicial facet.
<p>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.</p>
<p>See <a href=../src/libqhull/io.c#detvridge>qh_detvridge</a> for an example of ignoring tricoplanar facets.</p>
<h3><a href="#TOC">&#187;</a><a name="vertices">Voronoi vertices of a
region</a></h3>
<p>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
&quot;upperdelaunay&quot; if it corresponds to a Voronoi vertex
&quot;at-infinity&quot;. Qhull uses qh_printvoronoi in <tt>io.c</tt>
for '<a href=qvoronoi.htm>qvoronoi</a> <a href="qh-opto.htm#o">o'</a> </p>
<blockquote>
<pre>
/* please review this code for correctness */
qh_setvoronoi_all();
FORALLvertices {
site_id = qh_pointid (vertex-&gt;point);
if (qh hull_dim == 3)
qh_order_vertexneighbors(vertex);
infinity_seen = 0;
FOREACHneighbor_(vertex) {
if (neighbor-&gt;upperdelaunay) {
if (!infinity_seen) {
infinity_seen = 1;
... process a Voronoi vertex &quot;at infinity&quot; ...
}
}else {
voronoi_vertex = neighbor-&gt;center;
... your code goes here ...
}
}
}
</pre>
</blockquote>
<h3><a href="#TOC">&#187;</a><a name="ridge">Voronoi vertices of a
ridge</a></h3>
<p>Qhull uses qh_printvdiagram() in io.c to print the ridges of a
Voronoi diagram for option '<a href="qh-optf.htm#Fv2">Fv</a>'.
The helper function qh_eachvoronoi() does the real work. It calls
the callback 'printvridge' for each ridge of the Voronoi diagram.
</p>
<p>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. </p>
<h3><a href="#TOC">&#187;</a><a name="vneighbor">vertex neighbors of
a vertex</a></h3>
<p>To visit all of the vertices that share an edge with a vertex:
</p>
<ul>
<li>Generate neighbors for each vertex with
qh_vertexneighbors in <tt>poly2.c</tt>. </li>
<li>For simplicial facets, visit the vertices of each
neighbor </li>
<li>For non-simplicial facets, <ul>
<li>Generate ridges for neighbors with qh_makeridges
in <tt>merge.c</tt>. </li>
<li>Generate ridges for a vertex with qh_vertexridges
in <tt>merge.c</tt>. </li>
<li>Visit the vertices of these ridges. </li>
</ul>
</li>
</ul>
<p>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. </p>
+<h2><a href="#TOC">&#187;</a><a name="performance">Performance of
+Qhull </a></h2>
+
+<p>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 <i>O(log n)</i>
+bits. Empirically, the maximum number of vertices occurs at the
+end of constructing the hull. </p>
+
+<p>Let <i>n</i> be the number of input points, <i>v</i> be the
+number of output vertices, and <i>f_v </i>be the maximum number
+of facets for a convex hull of <i>v</i> vertices. If both
+conditions hold, Qhull runs in <i>O(n log v)</i> in 2-d and 3-d
+and <i>O(n f_v/v)</i> otherwise. The function <i>f_v</i>
+increases rapidly with dimension. It is <em>O(v^floor(d/2) /
+floor(d/2)!)</em>.</p>
+
+<p>The time complexity for merging is unknown. Options '<a
+href="qh-optc.htm#C0">C-0</a>' and '<a href="qh-optq.htm#Qx">Qx</a>'
+(defaults) handle precision problems due to floating-point
+arithmetic. They are optimized for simplicial outputs. </p>
+
+<p>When running large data sets, you should monitor Qhull's
+performance with the '<a href="qh-optt.htm#TFn">TFn</a>' 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. </p>
+
+<p>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. </p>
+
+<p>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. </p>
+
+<p>When building hulls in 20-d and higher, you can follow the
+progress of Qhull with option '<a href="qh-optt.htm#Tn">T1</a>'.
+It reports each major event in processing a point. </p>
+
+<p>To reduce memory requirements, recompile Qhull for
+single-precision reals (REALfloat in <tt>user.h</tt>).
+Single-precision does not work with joggle ('<a
+href="qh-optq.htm#QJn">QJ</a>'). Check qh_MEMalign in <tt>user.h</tt>
+and the match between free list sizes and data structure sizes
+(see the end of the statistics report from '<a
+href="qh-optt.htm#Ts">Ts</a>'). 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 <tt>user.h</tt>).</p>
+
+<p>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.</p>
+
+<p>To reduce the size of the Qhull executable, consider
+qh_NOtrace and qh_KEEPstatistics 0 in <tt>user.h</tt>. By
+changing <tt>user.c </tt>you can also remove the input/output
+code in <tt>io.c</tt>. 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.</p>
+
+<p>The precision options, '<a href="qh-optc.htm#Vn">Vn</a>', '<a
+href="qh-optc.htm#Wn">Wn</a>', '<a href="qh-optc.htm#Un">Un</a>'.
+'<a href="qh-optc.htm#An">A-n</a>', '<a href="qh-optc.htm#Cn">C-n</a>',
+'<a href="qh-optc.htm#An2">An</a>', '<a href="qh-optc.htm#Cn2">Cn</a>',
+and '<a href="qh-optq.htm#Qx">Qx</a>', may have large effects on
+Qhull performance. You will need to experiment to find the best
+combination for your application. </p>
+
+<p>The verify option ('<a href="qh-optt.htm#Tv">Tv</a>') 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.</p>
+
+<p>The check-frequently option ('<a href="qh-optt.htm#Tc">Tc</a>')
+becomes expensive as the dimension increases. The verify option
+('<a href="qh-optt.htm#Tv">Tv</a>') performs many of the same
+checks before outputting the results.</p>
+
+<p>Options '<a href="qh-optq.htm#Q0">Q0</a>' (no pre-merging), '<a
+href="qh-optq.htm#Q3">Q3</a>' (no checks for redundant vertices),
+'<a href="qh-optq.htm#Q5">Q5</a>' (no updates for outer planes),
+and '<a href="qh-optq.htm#Q8">Q8</a>' (no near-interior points)
+increase Qhull's speed. The corresponding operations may not be
+needed in your application.</p>
+
+<p>In 2-d and 3-d, a partial hull may be faster to produce.
+Option '<a href="qh-optq.htm#QGn">QgGn</a>' only builds facets
+visible to point n. Option '<a href="qh-optq.htm#QVn">QgVn</a>'
+only builds facets that contain point n. In higher-dimensions,
+this does not reduce the number of facets.</p>
+
+<p><tt>User.h</tt> 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. </p>
+
+<p>GNU <tt>gprof</tt> 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.
+
+</p>
<h2><a href="#TOC">&#187;</a><a name="enhance">Enhancements to Qhull </a></h2>
<p>There are many ways in which Qhull can be improved. </p>
<pre>
[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 ('<a href="qh-optc.htm#Vn">Vn</a>')
- determine the limitations of '<a href="qh-optq.htm#Qg">Qg</a>'
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 &quot;color&quot; 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 '<a href="qh-optg.htm#GDn">GDn</a>' 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 '<a href="qh-optf.htm#Fv">Fv</a>' 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 <a href="index.htm#orou94">'94</a> vertex-&gt;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-&gt;neighbors
</pre>
<p>Please let us know about your applications and improvements. </p>
<!-- Navigation links -->
<hr>
<p><b>Up:</b> <a href="http://www.qhull.org">Home
page for Qhull</a> <br>
<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of
Contents</a><br>
<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
&#149; <a href="qh-quick.htm#options">Options</a>
&#149; <a href="qh-opto.htm#output">Output</a>
&#149; <a href="qh-optf.htm#format">Formats</a>
&#149; <a href="qh-optg.htm#geomview">Geomview</a>
&#149; <a href="qh-optp.htm#print">Print</a>
&#149; <a href="qh-optq.htm#qhull">Qhull</a>
&#149; <a href="qh-optc.htm#prec">Precision</a>
&#149; <a href="qh-optt.htm#trace">Trace</a><br>
<b>To:</b> <a href="#TOC">Qhull code</a>: Table of Contents <br>
<b>Dn:</b> <a href="../src/libqhull/index.htm">Qhull functions</a>, macros, and data
structures <!-- GC common information -->
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
align="middle" width="40" height="40"></a><i>The Geometry Center
Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see changes.txt <!-- hhmts end --> </p>
</body>
</html>
diff --git a/html/qh-get.htm b/html/qh-get.htm
index d3093e9..399da61 100644
--- a/html/qh-get.htm
+++ b/html/qh-get.htm
@@ -1,122 +1,106 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Qhull Downloads</title>
</head>
<body>
<!-- Navigation links -->
<p><b>Up:</b> <a href="http://www.qhull.org"><i>Qhull Home Page</i></a><br>
</p>
<hr>
<h1><a
href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
src="../html/qh--cone.gif" alt="[CONE]" align="middle"
width="100" height="100"></a> Qhull Downloads</h1>
<ul>
<li><a href="http://www.qhull.org">Qhull Home Page</a> <p>Qhull
computes the convex hull, Delaunay triangulation, Voronoi diagram, halfspace
intersection about a point, furthest-site Delaunay
triangulation, and furthest-site Voronoi diagram. It
runs in 2-d, 3-d, 4-d, and higher dimensions. It
implements the Quickhull algorithm for computing the
convex hull. Qhull handles roundoff errors from floating
point arithmetic. It can approximate a convex hull. </p>
<p>Visit <a href="http://www.qhull.org/news">Qhull News</a>
for news, bug reports, change history, and users.
- If you use Qhull 2003.1 or 2009.1, please upgrade to 2012.1 or apply
+ If you use Qhull 2003.1 or 2009.1, please upgrade to 2015.0.2 or apply
<a href="http://www.qhull.org/download/poly.c-qh_gethash.patch">poly.c-qh_gethash.patch</a>.</p>
</li>
<li><a
- href="http://www.qhull.org/download/qhull-2012.1.zip">Download:
- Qhull 2012.1 for Windows</a> (2.1 Mbytes,
+ href="http://www.qhull.org/download/qhull-2015.0.2.zip">Download:
+ Qhull 2015.0.2 for Windows 10, 8, 7, XP, and NT</a> (2.1 Mbytes,
<a href="http://www.qhull.org/README.txt">readme</a>,
- <a href="http://www.qhull.org/download/qhull-2012.1.md5sum">md5sum</a>,
- <a href="http://www.qhull.org/download/qhull-2012.1-zip.md5sum">contents</a>)
- <p>Type: console programs for Windows 7 (32- or 64-bit), XP, and NT</p>
- <p>Includes executables, documentation, and sources files. It runs in a
- command window.</p>
+ <a href="http://www.qhull.org/download/qhull-2015.0.2.md5sum">md5sum</a>,
+ <a href="http://www.qhull.org/download/qhull-2015.0.2-zip.md5sum">contents</a>)
+ <p>Type: console programs for Windows (32- or 64-bit)</p>
+ <p>Includes 32-bit executables, documentation, and sources files. It runs in a
+ command window. Qhull may be compiled for 64-bits.</p>
</li>
- <li><a href="http://www.qhull.org/download/qhull-2012.1-src.tgz">Download: Qhull 2012.1 for Unix</a> (670K,
+ <li><a href="http://www.qhull.org/download/qhull-2015.0.2-src.tgz">Download: Qhull 2015.0.2 for Unix</a> (670K,
<a href="http://www.qhull.org/README.txt">readme</a>,
- <a href="http://www.qhull.org/download/qhull-2012.1.md5sum">md5sum</a>,
- <a href="http://www.qhull.org/download/qhull-2012.1-src-tgz.md5sum">contents</a>)
+ <a href="http://www.qhull.org/download/qhull-2015.0.2.md5sum">md5sum</a>,
+ <a href="http://www.qhull.org/download/qhull-2015.0.2-src-tgz.md5sum">contents</a>)
<p>Type: C/C++ source code for 32-bit and 64-bit architectures</p>
<p>Includes documentation, source files, two Makefile's, CMakeLists.txt, DevStudio projects, and Qt projects.
Includes preliminary C++ support and a preliminary Debian/autoconf build.</p>
<p>Debian, rpm, and Autoconf distributions are needed.</p>
</li>
<li><a href="http://gitorious.org/qhull">Gitorious Qhull</a> (git://gitorious.org/qhull/qhull.git)
<p>Type: git repository for Qhull. See <a href="http://www.qhull.org/src/Changes.txt">Changes.txt</a></p>
<p>Includes documentation, source files, C++ interface, and test programs. It builds with gcc, mingw,
CMake, DevStudio, and Qt Creator.
</p>
</li>
- <li><a href="http://download.opensuse.org/repositories/science/openSUSE_12.1/src/qhull-2012.1.2-31.1.src.rpm">Download:
- Qhull version 2012.1 rpm for OpenSuse 12.1</a> (707K)
- <p>Type: Rpm build for OpenSuse 12.1
- </p>
- </li>
<li><a
href="http://dl.acm.org/author_page.cfm?id=81100129162">Download:
Article about Qhull</a> (307K)
<p>Type: PDF on ACM Digital Library (from this page only)</p>
<p>Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T.,
&quot;The Quickhull algorithm for convex hulls,&quot; <i>ACM
Transactions on Mathematical Software</i>, 22(4):469-483, Dec 1996 [<a
href="http://portal.acm.org/citation.cfm?doid=235815.235821">abstract</a>].</p>
</li>
- <!--
- <li><a href="http://www.qhull.org/download/qhull-2009.1.3.tar.gz">Download: Qhull 2009.1.3 for Unix</a> (725K)
- <p>Type: Out-of-date C source code for Unix systems (qhull 2003.1). Includes patch for qh_gethash and -fno-strict-aliasing.</p>
- <p>Patch release of Qhull 2009.1 with Autoconf/Automake/Libtool support [R. Laboissiere].
- </p>
- </li>
-
---->
- <li><a href="http://packages.debian.org/sid/libqhull5">Download: libqhull5 2009.1 for Debian Unix</a> (1.3M)
- <p>Type: Out-of-date C source code for Unix systems. It may segfault if run with more than 2G memory (fix with
- <a href=http://www.qhull.org/download/poly.c-qh_gethash.patch>poly.c-qh_gethash.patch</a>)
+ <!---
+ <li><a href="http://software.opensuse.org/download.html?project=openSUSE%3AFactory&package=qhull">Download:
+ Qhull for OpenSuse</a> (707K)
+ <p>Type: Rpm build for OpenSuse 12.1, etc.
</p>
- <p>Qhull 2009.1 for Octave with Autoconf/Automake/Libtool
- support [R. Laboissiere]. If using gcc 4.1, 4.2, or 4.3, please compile qset.c with
- -fno-strict-aliasing (otherwise qhull segfaults) [Karas, Krishnaswami].
- See <a href=http://www.qhull.org/news/#bugs>Bugs</a> [Apr 2008].
- </p>
- </li>
+ </li>
+ -->
<li><a
href="http://www.qhull.org/download/qhull-1.0.tar.gz">Download:
Qhull version 1.0</a> (92K) <p>Type: C source code for
32-bit architectures </p>
<p>Version 1.0 is a fifth the size of version 2.4. It
computes convex hulls and Delaunay triangulations. If a
precision error occurs, it stops with an error message.
It reports an initialization error for inputs made with
0/1 coordinates. </p>
<p>Version 1.0 compiles on a PC with Borland C++ 4.02 for
Win32 and DOS Power Pack. The options for rbox are
&quot;bcc32 -WX -w- -O2-e -erbox -lc rbox.c&quot;. The
options for qhull are the same. [D. Zwick] </p>
</li>
</ul>
<!-- Navigation links -->
<hr>
<p><b>Up:</b> <a href="http://www.qhull.org"><i>Qhull Home Page</i></a><br>
<!-- GC common information --></p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img src="../html/qh--geom.gif" alt="[HOME]"
align="middle"></a> <i>The Geometry Center Home Page</i> </p>
<p>Comments to: <a href="mailto:qhull@qhull.org">qhull@qhull.org</a><br>
</body>
</html>
diff --git a/index.htm b/index.htm
index 16fd51d..6fc8e9b 100644
--- a/index.htm
+++ b/index.htm
@@ -1,280 +1,283 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Qhull code for Convex Hull, Delaunay Triangulation, Voronoi Diagram, and Halfspace Intersection about a Point</title>
</head>
<body>
<!-- Navigation links -->
<b>URL:</b> <a href="http://www.qhull.org">http://www.qhull.org</a>
<br><b>To:</b>
<a href="http://www.qhull.org/news">News</a>
&#149; <a href="http://www.qhull.org/download">Download</a>
&#149; <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">CiteSeer</a>
&#149; <a href=http://images.google.com/images?q=qhull&num=100>Images</a>
&#149; <a href="html/index.htm#TOC">Manual</a>
&#149; <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a>
&#149; <a href="html/qh-quick.htm#programs">Programs</a>
&#149; <a href="html/qh-quick.htm#options">Options</a>
</p>
<hr>
<!-- Main text of document -->
<table>
<tr><td valign=top>
<h1>Qhull</h1>
<a
href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
src="html/qh--cone.gif" alt="[CONE]" align="middle" width="100"
height="100"></a>
</td><td>
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.</p>
<!-- duplicated in index.htm and html/index.htm -->
<p>Qhull does <i>not</i> 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, </p>
-<p>Qhull 2012.1 fixes qhull-go for Windows 64-bit. If you use Qhull 2003.1. please upgrade to 2012.1 or apply <a href="http://www.qhull.org/download/poly.c-qh_gethash.patch">poly.c-qh_gethash.patch</a>.</p>
+<p>Qhull 2015.1 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 <a href="http://www. qhull.org/download/poly.c-qh_gethash.patch">poly.c-qh_gethash.patch</a>.
+</p>
</td></tr></table>
<hr>
<form method=get action=http://www.google.com/search>
<input type=hidden name=sitesearch value=www.qhull.org>
<input type=hidden name=num value=100>
<ul>
<li><a href="http://www.qhull.org/news">News</a> and
<a href="http://www.qhull.org/news/qhull-news.html#bugs">Bugs</a>
- about Qhull 2012.1 2012/02/18</li>
+ about Qhull 2015.0.2 2015/08/30</li>
<li><a href="http://www.qhull.org/download">Download</a> Qhull</li>
<li><a
href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/welcome.html">Examples
</a>of Qhull output </li>
<li><a href=http://gitorious.org/qhull/>Gitorious</a> C++ interface to Qhull
(<a href="http://gitorious.org/qhull/pages/Home">wiki</a>, <a href="http://www.qhull.org/src/Changes.txt">changes</a>)
<li><input name=as_q size=10 value="">
<input type="submit" value="Search">
www.qhull.org
<p>
<li><a href="http://www.qhull.org/news/qhull-news.html#users">How</a> is Qhull used?</li>
<li><a href="http://scholar.google.com/scholar?cites=13151392091060773178&as_sdt=40000005">Google Scholar</a>,
<a href="http://libra.msra.cn/Publication/232063/the-quickhull-algorithm-for-convex-hulls">Microsoft Academic</a>,
and <a href="http://citeseerx.ist.psu.edu/showciting?doi=10.1.1.117.405&sort=cite">CiteSeer</a>
references to Qhull
</p>
<li>
<a href=http://www.google.com/search?as_q=qhull+-debian+-cvs+-gentoo+-pool+-mirrors&num=100>Google</a> Qhull,
<a href="http://images.google.com/images?q=qhull&num=100">Images</a>,
<a href="http://www.google.com/#q=qhull&tbm=bks">Books</a>,
<a href="http://www.google.com/search?q=qhull&tbm=pts">Patents</a>,
<a href="http://groups.google.com/groups?as_q=qhull&num=100&as_scoring=d">Newsgroups</a>,
<a href="http://www.google.com/search?q=qhull&tbm=blg">Blogs</a>,
and <a href=http://www.googlism.com/who_is/q/qhull/>Who is</a> Qhull?
<p>
<li><a href=http://www.mathworks.com/>MATLAB</a> uses Qhull for their n-d computational geometry functions:
<a href=http://www.mathworks.com/help/techdoc/ref/convhulln.html>convhulln</a>
<a href=http://www.mathworks.com/help/techdoc/ref/delaunayn.html>delaunayn</a>
<a href=http://www.mathworks.com/help/techdoc/ref/griddatan.html>griddatan</a>
<a href=http://www.mathworks.com/help/techdoc/ref/voronoin.html>voronoin</a>.
</li>
<li>The <a href"http://cran.r-project.org/web/packages/geometry/geometry.pdf">geometry</a> package of <a href="http://www.r-project.org/">R</a> provides <a href="http://geometry.r-forge.r-project.org/">Qhull in R</a>.
<li>The <a href="http://packages.debian.org/sid/octave3.2">Debian build</a> of
<a href=http://www.octave.org/>GNU Octave</a> includes Qhull for computational geometry.
<li><a href=http://www.wolfram.com/products/mathematica/>Mathematica</a>'s Delaunay interface <a href=http://library.wolfram.com/infocenter/MathSource/1160/>qh-math</a>
and <a href="http://portal.uni-freiburg.de/imteksimulation/downloads/ims">QHullInterface</a>
<li><a href=http://www.geomview.org>Geomview</a> for 3-D and 4-D visualization of Qhull output
</ul>
</form>
<p><b>Introduction</b>
<ul>
<li><a
href="http://www.cs.mcgill.ca/~fukuda/soft/polyfaq/polyfaq.html"
>Fukuda's introduction</a> to convex hulls, Delaunay
triangulations, Voronoi diagrams, and linear programming</li>
<li><a
href="http://www.cse.unsw.edu.au/~lambert/java/3d/hull.html"
>Lambert's Java</a> visualization of convex hull algorithms </li>
<li><a
href="http://www.algorithmic-solutions.info/leda_guide/geometryalgorithms.html"
>LEDA Guide</a> to geometry algorithms
<li><a
href="http://mathworld.wolfram.com/ComputationalGeometry.html"
>MathWorld's</a> Computational Geometry from Wolfram Research
<li><a
href="http://www.cs.sunysb.edu/~algorith/major_section/1.6.shtml"
>Skiena's</a> Computational Geometry from his <i>Algorithm Design Manual</i>.
<li><a
href="http://www.cs.sunysb.edu/~algorith/major_section/1.6.shtml"
>Stony Brook</a> Algorithm Repository, computational geometry</li>
</ul>
<p><b>Qhull Documentation and Support</b>
<ul>
<li><a href="html/index.htm">Manual</a> for Qhull and rbox
<table><tr><td>
<ul>
<li><a href="html/index.htm#description">Description</a> of Qhull
<li><a href="html/qh-quick.htm#programs">Programs</a> and <a href="html/qh-quick.htm#options">Options</a>
quick reference
<li><a href="html/qconvex.htm">qconvex</a> -- convex hull
<li><a href="html/qdelaun.htm">qdelaunay</a> -- Delaunay triangulation
<li><a href="html/qvoronoi.htm">qvoronoi</a> -- Voronoi diagram
<li><a href="html/qhalf.htm">qhalf</a> -- halfspace intersection about a point
<li><a href="html/rbox.htm">rbox</a> -- generate point distributions
</ul></td><td><ul>
<li><a href="http://www.qhull.org/html/qh-faq.htm">Frequently</a> asked
questions about Qhull</li>
<li><a href="COPYING.txt">COPYING.txt</a> - copyright notice<br>
<li><a href="REGISTER.txt">REGISTER.txt</a> - registration<br>
<li><a href="README.txt">README.txt</a> - installation
instructions<br>
<li><a href="src/Changes.txt">Changes.txt</a> - change history <br>
<li><a href="html/qh-code.htm">Calling Qhull</a> from your program
<li><a href="src/libqhull/index.htm">Qhull functions</a>, macros, and data structures with source
</ul>
</td></tr></table>
<li>Send e-mail to <a href=mailto:qhull@qhull.org>qhull@qhull.org</a> </li>
<li>Report bugs to <a
href="mailto:qhull_bug@qhull.org">qhull_bug@qhull.org</a>
</ul>
<p><b>Related URLs</b>
<ul>
<li><a href="http://www.geom.uiuc.edu/software/cglist">Amenta's directory</a> of
computational geometry software </li>
<li><a href=http://www.boost.org/libs/graph/doc/table_of_contents.html>BGL</a>
Boost Graph Library provides C++ classes for graph data structures
and algorithms,
<li><a
href="http://www.netlib.org/voronoi/hull.html">Clarkson's
hull </a>program with exact arithmetic for convex hulls, Delaunay triangulations,
Voronoi volumes, and alpha shapes. </li>
<li><a href="http://compgeom.cs.uiuc.edu/~jeffe/compgeom/compgeom.html">Erickson's
Computational</a> Geometry Pages and
<a href="http://compgeom.cs.uiuc.edu/~jeffe/compgeom/code.html">Software</a>
<li><a
href="http://www.cs.mcgill.ca/~fukuda/soft/cdd_home/cdd.html">Fukuda's
cdd</a> program for halfspace intersection and convex hulls (<a
href="http://www.csb.ethz.ch/tools/polco">Polco/Java</a>)</li>
<li><a href="http://www.inf.ethz.ch/personal/gaertner/miniball.html">Gartner's
Miniball</a> for fast and robust smallest enclosing balls (up to 20-d)
<li><a href=http://www.algorithmic-solutions.com/enleda.htm>Leda</a>
and <a href=http://www.cgal.org/>CGAL</a> libraries for writing computational
geometry programs and other combinatorial algorithms
<li><a href=http://www.mathtools.net/>Mathtools.net</a> of scientific and engineering
software
<li><a href="http://morden.csee.usf.edu/dragon/kpalbrec/mesh.html">Owen's Meshing</a> Research Corner
<li><a
href="http://www-users.informatik.rwth-aachen.de/~roberts/meshgeneration.html">Schneiders'
Finite Element</a> Mesh Generation page</li>
<li><a href="http://www.cs.cmu.edu/~quake/triangle.html">Shewchuk's
triangle </a>program for 2-d Delaunay</li>
<li><a href=http://www.voronoi.com>Voronoi Web Site</a> for all things Voronoi
<li>Young's <a href="http://homepage.usask.ca/~ijm451/finite/fe_resources/">Internet Finite Element Resources</a>
<li><a href="http://www.uic.nnov.ru/~zny/skeleton/">Zolotykh's Skeleton</a> generates all extreme rays of a polyhedral cone using the Double Description Method</li>
</ul>
<p><b>FAQs and Newsgroups</b>
<ul>
<li><a
href="http://exaflop.org/docs/cgafaq/">FAQ</a>
for computer graphics algorithms
(<a href="http://exaflop.org/docs/cgafaq/cga6.html">geometric</a> structures)
</li>
<li><a
href="http://www-unix.mcs.anl.gov/otc/Guide/faq/linear-programming-faq.html">FAQ
</a>for linear programming </li>
<li><a href="news:comp.graphics.algorithms">Newsgroup</a>:
comp.graphics.algorithms </li>
<li><a href="news:comp.soft-sys.matlab">Newsgroup</a>:
comp.soft-sys.matlab</li>
<li><a href="news:sci.math.num-analysis">Newsgroup</a>:
sci.math.num-analysis </li>
<li><a href="news:sci.op-research">Newsgroup</a>:
sci.op-research </li>
</ul>
</blockquote>
<hr>
<p>The program includes options for input transformations,
randomization, tracing, multiple output formats, and execution
statistics. The program can be called from within your
application. </p>
<p>You can view the results in 2-d, 3-d and 4-d with <a
href="http://www.geomview.org">Geomview</a>. An alternative
is <a href=http://www.vtk.org/>VTK</a>.</p>
<p>For an article about Qhull, download from
<a href="http://dl.acm.org/authorize?89250">ACM</a> or <a
href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">CiteSeer</a>:
</p>
<blockquote>
<p>Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., &quot;The
Quickhull algorithm for convex hulls,&quot; <i>ACM Trans. on
Mathematical Software</i>, 22(4):469-483, Dec 1996, http://www.qhull.org</p>
</blockquote>
<p>Abstract: </p>
<blockquote>
<p>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. </p>
<p>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. </p>
</blockquote>
<!-- Navigation links -->
<hr>
<p><b>Up:</b> <a href="http://www.geom.uiuc.edu/software/past-projects.html"><i>Past Software
Projects of the Geometry Center</i></a> <br>
<b>URL:</b> <a href="http://www.qhull.org">http://www.qhull.org</a>
<br><b>To:</b>
<a href="http://www.qhull.org/news">News</a>
&#149; <a href="http://www.qhull.org/download">Download</a>
&#149; <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">CiteSeer</a>
&#149; <a href=http://images.google.com/images?q=qhull&num=100>Images</a>
&#149; <a href="html/index.htm#TOC">Manual</a>
&#149; <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a>
&#149; <a href="html/qh-quick.htm#programs">Programs</a>
&#149; <a href="html/qh-quick.htm#options">Options</a>
<!-- GC common information --></p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img src="html/qh--geom.gif" alt="[HOME]"
align="middle"></a> <i>The Geometry Center Home Page</i> </p>
<p>Comments to: <a href="mailto:qhull@qhull.org">qhull@qhull.org</a>
<br>
Created: May 17 1995 --- <!-- hhmts start -->
</body>
</html>
diff --git a/src/Changes.txt b/src/Changes.txt
index 52f9a1f..cad1e28 100644
--- a/src/Changes.txt
+++ b/src/Changes.txt
@@ -1,1912 +1,1944 @@
+$Id: //main/2011/qhull/src/Changes.txt#82 $
.............This file lists all changes to qhull and rbox.....................
------------
Need help
- Qhull needs RPM and Debian builds (CMake's CPackRMP and CPackDeb).
- - Add an Autotools build for everything
- - Set up debian build [octave-maintainers]
- Please keep debian files in config/
- Qhull needs a mirror/archive site for old and new builds
- Constrained delaunay triangulation via Shewchuk's algorithm (ACM Symp. Comp. Geo., 1998)
- The C++ interface needs work. Give it a try and make it better.
http://gitorious.org/qhull/
- - Document with Qt conventions using Doxygen (//! and //!<)
- Produce conformant triangulations for merged facets using option 'Qt'
+ - Write an incremental addPoint using bucketed inputs and facet location search
+ - Compute hyperplanes in parallel (cf. qh_setfactplane)
+ - Create Voronoi volumes and topology using a parallel implementation
-To do
- - Can allocate memory for QhullSet using Qhull.qhmem, Then default constructors for QhullVertexSet etc.
- - Review email for doc changes before jun'10
- - Git: Create signed tags for Qhull versions
- - Wiki: Add FIXUP to QH11026 for known problems
- - Review all FIXUP
- - Update README for libqhullr etc.
- - Notes to compgeom on conformant triangulation and Voronoi volume
- - Set File Ver and Product Ver in dll
- - Compute the convex hull of each Voronoi or Delaunay region
- - Performance test of qset and qhull
+------------
+To do for a future verson of Qhull
- Rescale output to match 'QbB' on input [J. Metz, 1/30/2014 12:21p]
- - qh-get.htm: List the Window OSs for Qhull [T. Winkler]
- - Add publications that compare Qhull and CGAL. Review results
- - Reconsider Qhull version numbering (e.g., Traveler 4/5/12)
- - Add interior point for automatic translation?
- - Allow comma separated input?
- - Allocate a new QhullPoint
- - countT -1 used as a flag in Coordinates.mid(), QhullFacet->id()
+ - Run through valgrind
+ - Notes to compgeom on conformant triangulation and Voronoi volume
+ - Git: Create signed tags for Qhull versions
+
+ - 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
+ 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?
- - Review all cpp code for 'int'
- - Review all c code for 'int'
- - RboxPoints.qh_fprintf_rbox, etc. message 9393 assumes countT but may be int, va_arg(args, countT); Need to split
- - vertexT unsigned id:24; /* too small */
- - Why QhullFacetList.PrintFacetList and .PrintFacet?
- - Remove s_qhull_output
- - qset_r.h defines countT -- duplicates code in user_h.h -- need to add to qset.h/user.h
- - rbox_errexit assumed to exit. Protect with a flag?
- - checkAndFreeQhullMemory does not work since it does not free qhmem itself.
- - Check base address for qhstatT, add Qhull initializers
- - Review all classes
- Check that assignment copies everything
- Check alignment for Fields
- Qhull& constructors before QhullQh* constructors, otherwise the same
- operator= for all
- check explicit
- Remove print(), add << T if needed
- Remove QhullFacet.print() -- Use << instead
- - Reduce includes
- - Document C++
- Designed for exploring the results of Qhull.
- All objects contain a QhullQh reference, making them memory inefficient.
- May also use libqhull (e.g., FOREACHfacet_(...))
- - Review default constructors (QhullPoint OK)
- - QhullVertexSet uses QhullSetBase::referenceSetT() to free it's memory. Probably needed elsewhere
+ 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
+ - Document C++ using Doxygen conventions (//! and //!<)
+ - Create a shared library for libqhullcpp. It must include all uses of QH_TRY and setjmp().
+ - 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
- - Review all tests
- Add QhullStat_test
- Add printIdentifiers to Set tests
- Add QhullVertexSet_test
- Add Qhull* to constructors
- Test QhullQh* constructors
- Test QhullFacetList.operator=
- Test QhullLinkedList.operator=
- Test QhullFacetSet.operator=
- Test QhullFacetSet.print("message")
- Test QhullPoints.operator=
- Test QhullPointSet.operator=
- Test QhullSet.operator=
- Test qh_NOmem, etc.
- - Reviewed
- QhullPoint_test
- - Update LASTerror for qhullpcpp.QhullError.h
- - Check that QtCreator can load and build with CMakefile
- - Incremental addition of input points to existing tesselation
- - Add reference (compares to cgal, http://www.mcs.anl.gov/papers/P5154-0614.pdf, 4x more memory, cgal much faster)
- Y. Liu and J. Snoeyink, “A Comparison of Five Implementations of 3D Delaunay Tessellation,” Combinatorial and Computational Geometry, vol. 52, pp. 439–458, 2005.
- - Fix no-more facets error
- - Fix interface to Qhull. Shouldn't do all the work in the constructor
- void runQhull(const char *qhullCommand2);
------------
-Dec'14 notes
-
-make-vcproj.sh -- Renames build/ to build-prev. Creates build, build-vc and build-qt (needs editing)
-Renamed build to build-new
-Copied build-prev to build and renamed as build-mar14
-Devenv loaded build/qhullr.sln with qhullmini
- build/qhulltest-mini/qhullmini.vcproj
- build/libqhullcpp/libqhullcpp.vcproj
- build/libqhullstaticr/libqhullstaticr.vcproj
-Includes
- build/libqhullr/libqhullr.vcproj
-
-Load Qt Creator (Oct'14) with src/qhull-all.pro -- The project is odd due to the include files
-Successfully compiled and ran qhullmini with QhullPoint_test
-Updated Perforce
-Added user_eg3
+Qhull 2015.0.2
+
+ Source code changes
+ - Increased size of vertexT.id and ridgeT.id to 2^32
+ 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()
-------------
-Qhull
- - Fixed documentation for 'include' path in qh-code.htm. It should be include/libqhull [fe rew]
- - Fixed documentation for 'i' in qconvex.htm. It triangulates in 4-d and higher [
- - Clarified qhalf space documentation for the interior point [J. Santos]
- - Rename debugging routines dfacet/dvertex to qh_dfacet/qh_dvertex
+ Other source code changes
+ - Define ptr_intT as 'long long' for __MINGW64__ [A. Voskov]
+ - 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., <stdio.h>
+ - 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
- - Rename user_eg, user_eg2, and user_eg3 to user_eg7,etc.
- - Rewrote user_eg, user_eg2, and user_eg3 as reentrant code
- Replace 'qhmem .zzz' with 'qhmem.zzz'
- - Removed spaces between function and parentheses
+ - Removed spaces between function name and parentheses
- Rename 'enum statistics' to 'enum qh_statistics'
- - Rename 'qh_rand_seed' to 'qh_last_random'. Declare it as DATA
- 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
- - After qh_meminit, qhmem.ferr is non-zero
+ - 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
+ - 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);
- - Set qhT.NOerrexit on initialization
- 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
-
-qhullr (reentrant Qhull)
- - Make the Qhull data structure (qh_qh) a parameter instead of a global static
- It simplifies multithreading and the C++ user interface
+ - 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
+ - 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
+ 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.")
- This replaces qh_QHpointer.
+ No more qh_QHpointer.
+ See user_eg3 and qhulltest
New libraries
- libqhullr -- Shared library with reentrant sources (e.g., poly_r.h and poly_r.c which replace libqhull's poly.h and poly.c)
- libqhullstaticr -- Static library with the same sources as libqhullr
- libqhullcpp -- The C++ interface using libqhullr (further notes below)
+ 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
- qhulltest -- Test the C++ interface using Qt
- testqsetr -- Test qset_r.c (the reentrant version of qset.c
- Renamed libraries and executables
- libqhullpcpp -- The old C++ interface using qh_QHpointer and libqhullp (previously called libqhullcpp)
- qhullptest -- The old test program for the C++ interface (previously called qhulltest)
+ testqset_r -- Test qset_r.c (the reentrant version of qset.c
- Source code changes for libqhullr
+ 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
-C++ interface
- - Reimplement C++ interface on reentrant libqhullr instead of libqhull
- - Renamed libqhullcpp to libqhullpcpp
- - Renamed qhulltest to qhullptest
- - Renamed qhull-app-cpp.pri to qhull-app-cpp_p.pri
+Changes to libqhullcpp
+ - Removed qhull_interface.cpp -- better to use Qhull.cpp.
+ If math.h breaks '#include qhull_a.h', preceed it with '#include math.h'
- 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<T>::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
- - Fixed double free by QhullVertexSet's copy constructor if qhsettemp_defined
+ - To avoid -Wshadow for QhullQh*, use 'qqh' for parameters and 'qh()' for methods
- Moved messaging from Qhull to QhullQh
- - RboxPoints(rboxCommand).comment() includes the command with its
- Add check of RboxPoints* in qh_fprintf_rbox
- Renamed Qhull.initializeQhull to Qhull.allocateQhullQh
- - Renamed UsingQhullLib.checkQhullMemoryEmpty to QhullQh.checkAndFreeQhullMemory
Added qh_freeqhull(!qh_ALL) as done by unix.c and other programs
- Moved QhullPoints.extraCoordinatesCount into QhullPoints.cpp
- - Changed QhullPoint.operator== to sqrt(distanceEpsilon)
- Replaced section tags with '#//!\name ...'
- - PointCoordinates.operator=: initialize QhullPoints, otherwise does not copy point_dimension
+ - 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
- Constructor requires Qhull or QhullQh* pointer
+ 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)
- Remove globals s_qhull_output= 0;
+ 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
- Constructor requires Qhull or QhullQh* pointer
- Reorganized
+ 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
- Constructor requires Qhull or QhullQh* pointer
- An empty QhullPoint sets point_dimension to hull_dim
- Added checks for point_coordinates==0, i.e., QhullPoint(q)
- Removed QhullPoint::id, use QhullPoint.id() instead
+ Add constructors for Qhull or QhullQh* pointer (for id() and operator==)
+ Add defineAs(coordT*)
+ Add getBaseT() and base_type for QhullSet<QhullPoint>
+ 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
- Removed test of qh_qh from operator==
+ If !qh_qh, operator==() requires equal coordinates
Use cout<<p instead of cout<<p.print()
Reorganized
- QhullPoints
+ Add constructors for Qhull and QhullQh* (for qh.hull_dim, QhullPoint::operator==)
+ Remove QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
Add operator=
Removed empty(). Use isEmpty() instead
- Constructor requires Qhull or QhullQh* pointer
Convert to countT
- operator==() if pointers are the same
- Remove test of qh_qh from operator==
+ operator==() tests if pointers are the same. Ituses distanceEpsilon if qh_qh is defined
Reorganized
+ - QhullPoints::Iterator and ConstIterator
+ Removed default constructors
+ Add constructors for Qhull and QhullQh* (for qh.hull_dim, QhullPoint::operator==)
+ Moved test of dimension from QHULL_ASSERT to operator==
+ Added QHULL_ASSERT of qh_qh
+ Convert to countT
- QhullPointSet
Constructor requires Qhull or QhullQh* instead of dimension()
Add operator=
Removed empty(). Use isEmpty() instead
Convert to countT
Always print print_message
Drop print(). Replace with print("")
+ - QhullQh
+ Added methods hasOutputStream(), disableOutputStream(), and enableOutputStream() (was Qhull UseOutputStream)
+ Add test of qh.NOerrexit to maybeThrowQhullMessage()
+ Add qhull_status, qhull_message, error_stream, output_stream from Qhull
+ Add factor_epsilon
- QhullRidge
Constructor requires Qhull or QhullQh* pointer
Dropped implicit conversion from ridgeT
Converted otherFacet() to 'const &'
Converted nextRidge3d() to 'const &'
+ Message for '<< QhullRidge' replaces " - " instead of preceeding it
- QhullSet
Removed empty(). Use isEmpty() instead
Constructor requires Qhull or QhullQh* pointer
Convert to countT
Add operator=
- QhullVertex
Constructor requires Qhull or QhullQh* pointer
Convert to countT
Dropped implicit conversion from vertexT
+ Add message to '<< QhullVertex'
- QhullVertexSet
Removed empty(). Use isEmpty() instead
Constructor requires Qhull or QhullQh* pointer
Convert to countT
- UsingQhullLib
Removed
Replace setGlobalDistanceEpsilon with setFactorEpsilon
Replace globalDistanceEpsilon with distanceEpsilon
-
+------------
Qhull 2012.1 2012/02/18 6.3.1.1494
- Fix CMakeLists for libqhull with MATCHES [P. Gajdos]
------------
Qhull 2012.1 2012/02/18 6.3.1.1490
Code changes
- Require option 'Qz' for Delaunay triangulation/Voronoi diagram
of cocircular/cospherical points [D. Sheehy]
- qh_errexit: Do not call qh_printsummary or qh_printstats on qh_ERRinput
- Change error QH6227 (all degenerate) from qh_ERRinput to qh_ERRprec
- Change error QH6159 (ID overflow) from qh_ERRinput to qh_ERRqhull
- eg/q_eg, q_egtest, q_test: Run if qconvex is in $PATH [M. Atzeri]
Build changes [M. Atzeri]
- Install to share/doc/qhull instead of share/doc/packages/qhull
- On Unix systems, install to share/man/man1 instead of man/man1
- CMakeLists: Remove the installation of user_eg* and testqset
- CMakeLists: Remove VERSION from qhull executables and libraries
- CMakeLists: Define qhull_SOVERSION instead of qhull_MAJOR
- CMakeLists: Set SOVERSION for shared libraries
- Rename libraries to qhull, qhull_d, qhull_p, and qhull_pd
libqhull6_p.vcproj is now libqhull_p.vcproj
mingw builds as libqhull.dll
cygwin builds as cygqhull-6.dll
linux builds as libqhull.so.6.3.1 with symbolic link as libqhull.so
- Developers using qhull 2011:
libqhull6.so is now libqhull_p.so. Do not use libqhull.so.
qhull6.dll is now qhull_p.dll. Do not use qhull.dll.
- Merged road/ into libqhullcpp/ and qhulltest/
Moved RoadLogEvent.* and RoadError.* to libqhullcpp
Moved RoadTest.* to qhulltest (requires Qt)
Installed RoadTest.h in libqhullcpp
Doc changes
- index.htm: Mathworks uses qhull for n-d
- qhull.htm: Fix qhull for qconvex
- qdelaun.htm/qvoronoi.htm: Use option 'Qz' for circular/cospherical inputs
- make help: Display targets
- Makefile: Better messaging
------------
Qhull 2012.1 2012/02/02 6.3.0.1483
Bug fixes
- Fixed qset.c for -fno-strict-aliasing. This gcc option is no longer needed
(disallow two pointers of differing types to the same memory location)
- Fixed error in qh_setappend_set if first set full and second set empty
- qh_setdelnth, qh_setdelnth_sorted: fixed wording of error message
- qh_setcheck: error message listed size and max backwards.
- qh_setequal: Allow NULL set as documented
- qh_setindex: Allow NULL set as documented
- qh_settemppush: report error if NULL
Code changes
- Add testqset: low level test of qset.c with mem.c
- qh_setendpointer: Implements QSet::endPointer()
- Assigned unique error code for qh_gethash
Build changes
- Added qhull.dll(.so) for Octave and other Debian builds
The global data structure qh_qh is statically defined (no qh_QHpointer)
Linked user_eg2 with qhull.dll (libqhull.so) instead of qhullstatic
Added qh_dllimport to libqhull.h for qhull.dll with MSVC
Changed qhull-app-shared.pri to use libqhull (without qh_QHpointer)
- Renamed libqhull6.so to libqhull6_p.so
Renamed qhull6.dll to qhull6_p.dll
The _p libraries (e.g., libqhull6_p.so) require -Dqh_QHpointer
Renamed qhull6.vcproj to libqhull6_p.vcproj
Added libqhullp/libqhullp.pro for shared library (libqhull6_p.so)
Added qhull-app-sharedp.pri for shared libraries with qh_QHpointer
- Install libqhull/*.htm files into include/libqhull
- Removed libqhull/qhull.h-deprecated [J. Eaton]
- Other changes to Makefile builds
Added 'make qtestall' as a smoketest of each qhull program
src/libqhull/Makefile: Use 'ar -rs ...' instead of ranlib
src/libqhull/Makefile: Fixed targets for cleanall
- Other changes to DevStudio builds
Moved pdb files for qhull libraries to lib/
AdditionalIncludeDirectories: Removed ../src/libqhullcpp
Use build-cmake/ for the DevStudio CMake build
- Other changes to Qt builds
Renamed qhull-libsrc.pri to qhull-libqhull-src.pri
- Added explicit d2u conversions to qhull-zip.sh
- Fixed \n vs. \r\n issues for Windows source files
Draft of Debian/AutoConf build (untested)
- Adjusted the Makefile.am's for the new directory structure.
- Added testqset to bin_PROGRAMS
- config/bootstrap.sh copies program sources into src/libqhull
- Kept qh_QHpointer=0 (static global data structure, qh_qh). It is faster.
Planning a new interface (qhull7?) which passes qh_qh as a parameter
- Added config/changelog from the 2003.1 Debian build
- Moved the debian/patches directory to config/
Optional patches to change smoketest message and turn on qh_QHpointer
- Deleted the debian directory. It was the old Debian build from 2003.1
Rafael Laboissiere's config directory replaced this build..
- Deleted Make-conf.sh (also the old Debian build)
Doc changes
- FAQ: Updated notes on computing volume of a Voronoi region
- Added direct link to ACM Digital Library for downloading the qhull paper
- Added link to Qhull in R
- qset.c: Updated notes about NULL sets
- qh_setappend: clarify qh_setappend for NULL newelem
- qh_setdellast: Fix head note
- Add build/README.txt
- Add uninstall instructions to README.txt and CMakeLists.txt
- Added instructions to create build/*.vcproj to CMakeLists.txt
- Update copyright to 2012
- Updated page links. Added Google books, patents, and blogs.
-----------
Qhull 2009.1.3 2011/12/06
configure: Add -fno-strict-aliasing if $GCC, Required for gcc 4.1+
------------
Qhull 2011.2 2011/11/29 6.2.1.1446
Bug fixes
- qh_new_qhull: Call qh_prepare_output if !outfile [A. Aldoma]
No effect on qhull users since qh_prepare_output is always called.
- Replace Qhull-go.pif with Qhull-go.lnk for Windows 7 64-bit [lots]
- Error if qh_newhashtable, qh_setnew, or qh_memalloc overflows [X. Cheng]
For example, 'rbox 64 D32' overflows hash table for qh_matchnewfacets
Qhull uses 32-bit ints for identifiers, counts, and sizes. See "WARN64"
- q_eg, q_test: change tail +3 to tail -n +3 [N. Dubray, M. Atzeri]
- Qhull-go.bat: Changed 'cmd' to '%comspec%'
Build changes
- Added src/libqhull/Makefile for simple gcc build of executables and lib
- qhulltest.vcproj: Replaced full path to QT with $QTDIR (e.g., c:/qt/4.7.4)
- Split userprintf_rbox.c from userprintf.c,
Otherwise qhull brings in rboxlib and rbox brings in libqhull
- Makefile: qhullx target must be after LIBQHULLS_OBJS
- Makefile: Explicitly list rbox dependencies for qhullx target
- MBorland: Fixed tabs
- Placed $LIBQHULLS_OBJS in same order. Frequently called ones together.
- Update file lists for Make-config.sh [O. Lahaye]
- CMakeLists: add README.txt,etc. to DOC_INSTALL_DIR [M. Atzeri]
- Restored qhull.h-deprecated.
qhull.h conflicts with Qhull.h on Windows systems [C. Abela]
- make-config.sh: Add warning that it is out-of-date
- Remove extra space in '#! /bin/sh' in q_eg, etc. [P. Cheeseman]
Source changes
- libqhull.h: Added qh_True and qh_False for True/False [A. Mutzel]
Did not remove or replace True/False since it is used everywhere
- Moved error message from qh_argv_to_command to caller. Avoids dependency.
- user_eg3.c: Use '10 D2' as default rbox (e.g., 'user_eg3 rbox qhull d')
- user.c, user_eg2.c: Add test of qh_qh as done in user_eg.c
- q_test: Removed duplicate test of qhull C-0.02
Documentation
- index.html: Added ACM Authorizer link to ACM Trans. Math. Software
- Split Delaunay and Voronoi FAQs
- FAQ: How to compute the volume of a Voronoi region [C, Brinch]
- Add 'FS' to qconvex prompt (total area and volume)
- Add clarification to 'Fv' about corner input sites [O. Can]
- Qhull-go.bat: Removed out-of-date advice. Added title.
- qh-code.htm: Updated the discussion of multi-threading for C++ [I. Pirwani]
Qhull 2009.1.2 2011/11/21
- Revert to LF line endings [P. Cheeseman]
- Remove out-of-date material from qhull-go.bat
- Replaced QHULL-GO with a lnk file
Qhull 2011.1 2011/05/23 6.2.0.1385 (exe/dll files unchanged)
- delaunay.vcproj: Fixed qhullstatic_d.lib for debug and minrelsize builds
- Did not redate the distribution
Qhull 2011.1 2011/05/18 6.2.0.1385 (exe/dll files unchanged)
- Add 'm' library to shared and static targets on Unix [A. Bouchard]
Qhull 2011.1 2011/05/14 6.2.0.1383 (exe/dll files unchanged)
- PointCoordinates.cpp: Add #include <iterator> [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()
- Add 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 &#187;
- 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 <time.h> for CLOCKS_PER_SEC
- Move ostream<<QhullFacetList from inline to compiled.
- Removed ConvexHull/ from git. Not used.
------------
qhull 2009.1.1 2010/01/09
- Patch release of 2009.1.
qh_gethash allowed a negative result, causing overwrite or segfault
See git:qhull/project/patch/qhull-2003.1/poly.c-qh_gethash.patch
Compared results of q_test, q_eg, q_egtest with patched poly.c, qhull-2003.1
------------
qhull 2010.1 2010/01/07
- Assign type to qh.old_qhstat and memT.tempstack [amorilia]
- Replace tabs with spaces.
- Fix qh_pointid in case ptr_intT is unsigned
qhull 2010.1 2010/01/06
- Fixed serious bug in qh_gethash [poly.c]
- Documentation and build system are incomplete (see above)
- First release of C++ interface [qh-code.htm]
- Development moved to http://gitorious.org/qhull
git clone git@gitorious.org:qhull/qhull.git
- Did not fix conformant tesselations for 'Qt'.
For details, see http://www.qhull.org/news#bugs of May 2007 and Dec 2006.
- Use g++ builds for Windows distribution (10% faster than msvc2005)
Combined vcproj/ and qtproj/ into project/
vcproj will be replaced by qmake generated files
------------
qhull 2010.0.3 2010/01/05
Fixed bugs
- 'QJn': Fix qh.STOPcone in qh_build_withrestart(). It was not cleared.
- qh_initqhull_outputflags [global.c]: warn about Qc only if QHULLfinished
otherwise set if needed
qhull 2010.0.2 2010/01/04
Fixed bugs
- qh_gethash [poly.c]: fix sign conversion.
Previously, the result may be negative, leading to a segfault.
The bug is more likely with large address spaces
Reviewed all uses of %(modulo) for remainder with negative arguments
- Reviewed output of q_test and compared to results from 2003.1
Breaking code changes
- Return type of qh_gethash changed from unsigned to int. Matches 'size'
- addhash takes a signed hash
qh_addhash( newelem, hashtable, hashsize, hash )
Code changes
- Test for qh_qh in qh_printf
- Makefile.txt corrected for libqhull build [amorilia]
- Renamed index to idx to avoid shadowing BSD strings.h [kwilliams]
qhull 2010.0.1 2010/01/03
New Features:
- Added option 'Ta' to annotate output with message codes
Preliminary C++ support:
- C++ declarations may change without warning
- Preliminary documentation for Qhull's C++ interface [qh-code.htm#cpp, qhull-cpp.xml]
- Added user_eg3 as an example of Qhull.cpp
- Removed qhull_interface.cpp
Changes to qhull options and results
- Allow 'd' and 'v' as the filename for 'TO ..' and 'TI ...' in qdelaunay [M. Jambon]
- 'rbox tN' requires an integer (previously allowed floats)
- Allow quoted filenames for 'TO ...' and 'TI ...'
- Prefix error messages and warnings with a message code (e.g., QH6012)
- Fixed rbox ignoring flags that were not separated by spaces
- Report all hidden options before exiting in qh_checkflags()
- Defined qh_OPTIONline [user.h] as max length of option line ('FO')
- Report error if negative arguments to rbox 'G', 'L', 'Z'
- Unknown rbox flag changed from a warning to an error
- Set error status 4 qh_ERRmem if rbox runs out of memory
- Removed extra spaces at end of line
Breaking Code Changes:
- Renamed qh.coplanarset to coplanarfacetset. Avoids conflict with facetT.coplanarset
- qh_restore_qhull() zeroes out qh.old_qhstat and qh.old_tempstack. Ownership moved.
- Rewrote save_qhull/restore_qhull
- Add Ztotcheck to zzdef_ [R. Gardener]
- Changed qh_malloc to size_t (was unsigned long)
- Declare qh_PRINT instead of int [kwilliams]
- In qh_printafacet(), changed error output to 'qh ferr'
Bug fixes to C code:
- Use gcc 4.4.0 or later. gcc 4.2.1, 4.2.2, and 4.3.2 -O2 segfaults in qset.c . gcc 4.1.1 was OK
See bug report http://gcc.gnu.org/ml/gcc-bugs/2007-09/msg00474.html
- Rewrite qh_setappend to avoid g++ 4.1, 4.2, and 4.3 strict_aliasing error.
Orion Poplawski (orion@cora.nwra.com)
http://www.rpmfind.net/linux/RPM/fedora/12/ppc/qhull-devel-2003.1-13.fc12.ppc64.html
- Fixed qh_findfacet_all(), "REALmin" should be "-REALmax" [L.A. Taylor].
Effects library users for convex hulls and halfspace intersections.
- qh_printfacet [io.c] Removed extra space for neighboring facets
- Report error if d points, Delaunay, and not Qz
- Fixed double-free of facet->centrum for triangulated facets
- Fixed mindist initialization if !testcentrum in io.c findbest_test [Ratcliff]
- Fixed parentheses around warning for missing 'Qc' [qh_initqhull_outputflags]
- Fixed rbox buffer overflow of 'command' when appending seedbuf
- Fixed option string for 'rbox t t999'. Although seed was correctly set to 999,
a random seed was appended to the rbox comment (e.g., 'rbox t t999 t32343')
- Fixed upper bound of sanity check for qh_RANDOMmax in qh_initqhull_globals()
Changes to C code
- Reordered #include from specific to general. Move up .h for module.
- Removed qh.old_stat -- never used
- Removed qh_clearcenters from qh_freeqhull. Duplicated by qh_delfacet
- qh_printcenter [io.c] removed unreachable fprintf argument
- qh_getarea() [geom2.c] ignored on multiple calls (qh.hasAreaVolume)
- qh_getarea() [geom2.c] checks facet->isarea. Set by QhullFacet.facetArea()
- qh_triangulate() [poly2.c] ignored on multiple calls (qh.hasTriangulation)
- Add statistics for vertex_visit and visit_id to buildtracing
- Defined scale and offset parameters for qh_randomfactor
Bug fixes and changes to mem.c/mem.h
- Fixed qhmem.totshort (total short memory in use)
- Memory tracing (T5) redone for sort order by object
- Added full tracing for short memory allocations.
- Added qhmem.totfree (total short memory on freelists)
Increases size of qh_memalloc_ and qh_memfree_
- Added qhmem.totdropped (leftover freesize at end of each short buffer)
- Added qhmem.totunused (short size - request size)
- Added qhmem.totbuffer (total short memory buffer w/o links)
- Added memory statistics to qh_NOmem;
- Added qh_memtotal to track allocated memory
- Renamed qh_memfree parameter to 'insize' for consistency with qh_memalloc
- Removed qhmem.curlong. qa_memfreeshort computes curlong from cntlong and cntfree
- In mem.h, changed ptr_intT to long. qh_meminit() checks that it holds a 'void*'
Fixed g++ and devstudio warnings
- Except for bit field conversions, compiles cleanly with
-Wall -Wextra -Wshadow -Wcast-qual -Wwrite-strings -Wno-sign-conversion -Wconversion
- Fixed warnings at VC8, level 4
- Fix data types to remove conversion warnings [kwilliams]
- Use size_t for calls to malloc,etc [kwilliams]
Retained int sizes for qset.h and mem.h. Follows Qt convention
and is easier to work with. int can be 64-bits if 2 billion facets
- Change literal strings to const char* [kwilliams]
- Added type casts to SETfirst and SETsecond [amorilia+alphax]
- getid_() returns an int [kwilliams]
- Add missing const annotations [kwilliams]
- Fixed 64-bit warnings (marked with "WARN64")
- Convert sizeof to (int) for int parameters
- In libqhull.c, added explicit casts from long to float, Avoids warning
- In global.c, cast time() to int for QRandom-seed. Avoids warning
Changes to C code for C++ support
- Add sln, vcproj, and qtpro files for building Qhull -- add to README notes
- Added dim to vertexT for cpp interface. Reduced size of qh.vertex_visit
- qh_produce_output [io.c] may be called multiple times (C++ interface)
- Moved SETsizeaddr_() to qset.h for use by QhullSet.cpp
- Option 'Tz' sets flag qh.USEstdout for QhullPoints.cpp
- Added support for multiple output runs from QhullPoints.outputQhull
- qh_clear_outputflags() resets the output flags
- qh_initqhull_outputflags split from qh_initqhull_globals
- Added qh.run_id, a random identifier for this instance of Qhull (QhullPoints)
- For qh.run_id, initqhull_start initializes qh_RANDOMseed to time instead of 1
- Extracted qh_argv_to_command (random.c) from qh_init_qhull_command and fixed a buffer overflow
- Moved qh_strtod/qh_strtol from global.c to random.c for use in rboxlib.c
- Split out random functions into random.c
- Added message codes to qh_fprintf(). See its definition in user.c
- Replaced exit, malloc, free, fprintf, and fputs with qh_malloc,...[J.W. Ratcliff]
- Added qh_fprintf, qh_malloc, qh_free, ph_printhelp_narrowhull to user.c
- Moved qh_printhelp_degenerate and qh_printhelp_singular from io.c to user.c
- Clear qh.ERREXITcalled at end of qh_errexit().
Documentation:
- Fixed out-of-date CiteSeer references
- Renamed html/qh-in.htm to html/qh-code.htm
- Add reference to 'Qt' to 'i'
- Add reference to 'FS' to 'FA'
- qh-impre.htm discusses precision issues for halfspace intersection
- Add cross references between options 'FA' and 'FS'
- Added link to Wolfram Research's MathWorld site
- Updated Fukuda's links
- Changed copyright to C.B. Barber for C++, documentation, and merge.c
- Updated Qhull citation with page numbers.
- Proposed project: constructing Voronoi diagram
- Proposed project: computing Voronoi volumes
- Replaced tabs with spaces in qhull.txt and rbox.txt
------------
qhull 2009.1 2009/6/11
This is a maintenance release done by Rafael Laboissiere <rafael@debian.org>.
- src/rbox.c (main): Avoid problems of evaluation order when
pre-incrementing arguments of strtod
- src/io.c (qh_produce_output), src/stat.c (qh_initstatistics): Use %lu
instead of %d in the format string for arguments of type size_t
- html/qhull.man, html/rbox.man: Fix several syntax, macros, and hyphen
problems in man pages
- The Autotools files have been generated with modern version of autoconf (2.63),
automake/aclocal (1.10.2), and libtool (2.2.6)
- Some character issues in the man pages are fixed
------------
qhull 2003.1 2003/12/30
New Features:
- Add Maple output ('FM') for 2-d and 3-d convex hulls [T. Abraham]
Breaking Code Changes:
- Annotate C code with 'const'. An ANSI compatible compiler is required.
Bug Fixes and Code Changes:
- Fixed qh_findbest() for upperdelaunay facets w/o better, lower neighbors
For library users and some qhull users [A. Cutti, E. Milloti, K. Sun]
- Preserved qhmem.ferr in qh_memfreeshort() for library users
- Removed 'static' from qh_compare... for io.h and merge.h [V. Brumberg]
- Split out qh_initqhull_start2() to avoid allocating qh_qh
- Split out qh_freeqhull2() to avoid freeing qh_qh
- Split out qh_produce_output2() and qh_prepare_output()
- qh_initstatistics() frees a previously existing qh_qhstat
- qh_initqhull_start2() checks that qh_initstatistics() called first
Documentation:
- Add warning to findDelaunay() and qh_in.htm about tricoplanar facets
- Noted Edelsbrunner's Geometry & Topology for Mesh Generation [qh-impre.htm]
- Noted Gartner's Miniball algorithm [qh_impre.htm]
- Noted Veron and Leon's shape preserving simplification [qh_impre.htm]
qhull 2003.1 2003/12/19
Bug Fixes:
- Reversed coordinate order for qh.ATinfinity in qh_projectinput [V. Brumberg]
This effects:
Qhull library 'd' or 'v' users with 'Qz' and unequal coordinate ranges.
qdelaunay/qvoronoi users with 'Qbk:0Bk:0', 'Qz', and unequal coordinate ranges
Changes to code:
- Replaced qh_VERSION with qh_version in global.c [B. Pearlmutter]
The previous techniques were either clumsy or caused compiler errors
- Removed unused variables from qh_findbest and qh_findbestnew [B. Pearlmutter]
- Note that qh.TESTpoints was added in 2002.1 for tsearch implementation
Changes to distribution:
- Added Unix distribution including Debian files [R. Laboissiere]
The previous Unix distribution is now the source distribution
- Added rpm distribution [L. Mazet]
- Investigated generation of Win32 dll. Need to define a C++ interface.
Changes to documentation:
- Moved Qhull to www.qhull.org (geom.umn.edu is not available)
- The Geometry Center is archived at http://www.geom.uiuc.edu
- Reviewed introduction to each program
Triangulated output ('Qt') is more accurate than joggled input ('QJ')
qdelaunay is 'qhull d Qbb' [C. Ulbrich]
qvoronoi is 'qhull v Qbb'
Added example of non-simplicial intersection to halfspace intersections
- Added warning about using the Qhull library.
- Added qhull timings to When to use Qhull [C. Ulbrich]
- Reorganized the home page index and the manual index
- Moved qh-home.htm to index.htm
Changes to examples
- Fixed options for eg/eg.t23.voronoi.imprecise [B. Pearlmutter]
------------
qhull 2002.1 2002/8/20
Changes to distribution:
- Set up savannah.nongnu.org/projects/qhull/ [R. Laboissiere]
- Set up www.thesa.com as a backup
- Added qh-get.htm, a local copy of the download page
- Added Visual C++ interface to Qhull, qhull_interface.cpp [K. Erleben]
- Use HTTP instead of FTP for downloading Qhull
- Renamed qhull-1.0.sit.hqx
Bug fixes:
- Fixed sign of coefficients for cdd halfspaces ('FD','Fd') [T. Abraham]
Changes to code:
- Replace qh_version with qh_VERSION in libqhull.h.
Allows shared libraries and single point of definition
- Added qh.TESTpoints for future implementation of tsearch
Changes to build
- Makefile.txt works under cygwin
- Added Make-config.sh to create a Debian build [R. Laboissiere]
- Added .exe to Makefile.txt#clean.
- In README, use -fno-strict-aliasing with gcc-2.95.1 [Karas, Krishnaswami]
- Fixed chmod in Makefile.txt [B. Karas]
Documentation updates
- Documented input options for each program [A. Montesinos]
- FAQ: "How to get the radii of the empty spheres for Voronoi vertices"
URL updates:
- Changed official URL from locate/qhull to software/qhull
- Changed URLs from relative to absolute in qh-home.htm and qh-get.htm
- Added URL for Newsgroup: comp.soft-sys.matlab
- Added URL for GNU Octave
- Added URLs for Google and Google Groups
- Replaced qhull_mail.html and qhull_bug.html with mailto links.
- Removed URL for Computational Geometry Tribune
- Changed URL for locate/cglist to software/cglist
- Used site relative links for qh-home.htm
------------
qhull 3.1 2001/10/04
New features
- Added option 'Qt' to triangulate non-simplicial facets
- Added option 'TI file' to input data from file
- Added option 'Q10' to prevent special processing for narrow distributions
e.g., RBOX 1000 L100000 s G1e-6 t1001803691 | QHULL Tv Q10
- Tried to compute Voronoi volumes ('Pv'). Requires dual face graph--not easy
See Clarkson's hull program for code.
Changes to options
- Added numtricoplanars to 'Fs'. Number of good, triangulated facets for 'Qt'
- Added Zdelvertextot to 'Fs'. If non-zero and Delaunay, input is degenerate
- Qhull command ('FQ') may be repeated.
- If 'TPn' and 'TWn' defined, trace the addition of point 'n'
otherwise continue tracing (previously it stopped in 4-d)
- Removed 'Ft' from qdelaunay. Use 'Qt o' or 'qhull d QJ Qt' instead.
For non-simplicial regions, 'Ft' does not satisify the Delaunay property.
- If 'Po' or 'TVn', qhull checks outer planes. Use 'Q5' to turn off.
- If 'T4', print facet lists and check polygon after adding each point
Corrections to code
- rbox: allow 'c' and 'd' with 's r', meshes, etc.
- qh_findbest: redesigned as directed search. qh_findbesthorizon for coplanar
qh_findbest is faster for many distributions
- qh_findbestnew: redesigned to search horizon of coplanar best newfacets
needed for distributions with a sharp edge,
e.g., rbox 1000 s Z1 G1e-13 | qhull Tv
- qh_findbest/qh_findbestnew: search neighbors of better horizon facets
was needed for RBOX 1000 s Z1 G1e-13 t996564279 | qhull Tv
and RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv
- qh_findbest with noupper: could return an upperdelaunay facet if dist>qh.MINoutside.
- qh_findbestnew: allow facet->upperdelaunay if dist > qh.MINoutside
- qh_partitioncoplanar: call qh_partitionpoint if outside and perpendicular
for distributions with a sharp edge
- qh_partitionvisible: report precision error if all newfacets degenerate.
was needed for RBOX 1000 s W1e-13 t995138628 | QHULL d
- qh_createsimplex: clears qh.num_visible, may be non-zero with 'TRn QJ'
Changes to prompts, warnings, and statistics
- For Delaunay & Voronoi, 's' reports deleted vertices due to facet merging.
They were incorrectly reported as nearly incident points.
- Warn if recompute centrum after constructing hull
- Simplified narrow hull warning and print all digits of cosine.
A narrow hull may lead to a point outside of the hull.
- Print total vertices deleted instead of ave. per iteration (Zdelvertextot)
- Improved tracing for qh_partitionpoint and qh_partitioncoplanar
- Added number of distance tests for checking outer planes (qh_check_maxout)
- Simplified "qhull precision error: Only n facets remain."
- Included 'TRn' in the causes of a premature exit
Changes to documentation
- README.txt: Added quickstart instructions for Visual C++
- rbox: Added example of edge of narrow lens, rbox 1000 L100000 s G1e-6
- Added cross references between options 'o' and 'p'.
- qh-eg.html: added examples comparing 'Qt', 'QJ', and neither 'Qt' nor 'QJ'
eg.15a.surface, eg.15b.triangle, eg.17a.delaunay.2, etc.
- Reorganized and enhanced discussion of precision problems in qh_impre.htm
- Fixed spelling errors [K. Briggs]
- Fixed link errors, validated HTML, and spell checked [HomeSite]
- Removed unnecessary #TOP links
- Added source links to the qh-quick.htm's header and footer
- qh-geom.htm, qh-poly.htm: add links to Voronoi functions in io.c
- src/index.htm: Added how to search libqhull.h for qhull options
- qvoronoi.htm/qdelaun.htm: 'Fc' and 'FN' includes deleted vertices
Changes to URLs
- Added http://www.voronoi.com and http://www.magic-software.com
Changes to code
- qh_qhull: if 'TVn' or 'TCn' do not call qh_check_maxout and qh_nearcoplanar
- reviewed time profile. Qhull is slower. Optimized qh_findbestnew()
- qh_addpoint: Added warning note about avoiding a local minimum
- qh_checkpolygon: report qh.facet_next error if NARROWhull & dist>MINoutside
- qh_findbest: renamed "newfacets" parameter to "isnewfacets" since it is boolT
- qh_findbest/qh_findbestnew: testhorizon even if !MERGING
Otherwise qhull c D6 | qhull Q0 Tv assigns coplanar points
- qh_resetlists: add qh_RESETvisible for qh_triangulate
- qh_findbest: search better facets first. Rewritten.
- qh_findbest: increased minminsearch, always check coplanar facets.
See: RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv
- qh_findbestnew: report precision error for deleted cones [rare event]
e.g.: RBOX 1000 s W1e-13 P0 t1001034076 | QHULL d Qbb Qc Tv
- qh_findbesthorizon: search horizon of qh.coplanarset. New.
- qh_findbestsharp: replaced with qh_sharpnewfacets followed by qh_findbestnew
- qh_partitionpoint, Delaunay sites can not be inside. Otherwise points may
be outside upperDelaunay facets yet not near-inside Delaunay facets
See: RBOX s 1000 t993602376 | QHULL C-1e-3 d Qbb FA Tv
- qh_partitioncoplanar: call qh_findbest/qh_findbestnew with qh DELAUNAY
- qh_printlists: format long lines
- qh_printvertex: format long lines
- user.h: tightened qh_WARNnarrow and qh_MAXnarrow. Do not see problems
until they are -1.0.
- user.h: defined qh_DISToutside, qh_SEARCHdist, and qh_USEfindbestnew
- qh_checkfacet: in 3-d, allow #ridges > #vertices. Can get a vertex twice
in a ridge list, e.g, RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv
Changes to FAQ
- Recommended use of triangulated output ('Qt')
Changes to distribution
- Recompiled in Visual C++ 5.0 with optimization (as was version 2.6)
- q_test: Added bad cases for Qhull and tests for new features
Changes to Qhull library
- Added qh_triangulate() to poly2.c. It triangulates the output.
- Added option 'Q11' to copy normals and recompute centrums for tricoplanar facets
'FP' may not print the nearest vertex for coplanar points
Use option 'Q11' when adding points after qh_triangulate()
------------
qhull 3.0 2001/02/11
Changes to distribution
- added qconvex, qdelaunay, qhalf, and qvoronoi
- added qhull-interface.cpp on calling Qhull from C++ [K. Erleben]
- renamed to qhull3.0/.
- added eg/, html/, and src/ directories
Changes to URLs
- MathLab6 qhull: convhulln, delaunayn, griddatan, tsearchn, vororoin [Z. You]
- Wolfram Research wrote a Mathematica interface for qdelaunay [Hinton]
- Geomview moved from www.geom.umn.edu to www.geomview.org [M. Phillips}
- added URLs for tcsh and cygwin to README.txt
Changes to documentation
- reorganized table of contents and renamed qh-man.htm to index.htm
- wrote program documentation, dropped qh-opt.htm and qh-optv.htm
- added quick reference, qh-quick.htm
- reorganized qh-rbox.htm and renamed it to rbox.htm
- split up qh-c.htm for quick navigation
Corrections to code
- fixed type of arg for error message in qh_initqhull_globals [N. Max]
- fixed incorrect initialization of qh MINdenom_1 for scalepoints
- fixed drop dim for 'H Qbk:0Bk:0'. Added qh.feasible_point to qh_projectinput
- qh_WARNnarrow is angle between facet normals. Negate for warning message.
- statistics for Wangle/etc. concerns facet normals. Reworded [E. Voth]
- fixed error message for 'FC v'
- report cospherical points if Delaunay and error in qh_scalelast()
Changes to code
- turn on Pg if (QVn or QGn) and not (Qg or PG)
- turn on Qc if format option 'Fc', 'FP', or 'Gp' (removes warning)
- removed last good facet unless ONLYgood ('Qg').
- added count of non-simplicial or merged facets to 'FS'
- added count of non-simplicial facets to 's' (OK if #vertices==dim)
- added Znonsimplicial and Znowsimplicial to 'Ts'
- allow Mathematica output of dual polytope for halfspace intersection
- added qh_checkflags to globals.c for multiple front ends
- qh_initqhull_globals sets qh.MERGING if qh.MERGEexact
- removed hashentryT. It is no longer used.
Changes to prompts and warnings
- reorganized prompts
- reorganized synopsis for rbox.c
- print warning if 'Fc' or 'FP' with 'd QJ'. Coincident points are unlikely.
- ignore warning if options 'v i Pp'. qvoronoi users may need Delaunay tri.
- reworded warning if 'Pg' and 'QVn' is not a vertex.
- reworded warning for 'Qx Tv', qh_check_points() in poly2.c
- if 'Pp', turn off warning for 'Qbb' without 'd' or 'v'
- in qh_printsummary() of Voronoi and Delaunay, distinguish QVn, QGn, Pdn, PDn
Changes to FAQ
- added FAQ item for nearly flat Delaunay triangles [Z. You]
- added FAQ item for area and volume [R. Konatham]
- added FAQ item for Voronoi diagram of a square [J. Yong]
- edited FAQ item on point location in Delaunay triangles [Z. You]
- added FAQ item on nearly flat Delaunay triangles [Dehghani]
- added FAQ item about halfspace intersection [V. Tyberghein]
- added FAQ item for missing ridges [M. Schmidt]
- added FAQ item about qh_call_qhull [R. Snyder]
- added FAQ item about memory statistics [Masi]
- added FAQ item on meshing non-convex objects
- added FAQ item on MATLAB and Mathematica interface
------------
qhull 2.6 1999/04/19
- fixed memory overwrite (no effect) in qh_initstatistics() [K. Ford]
- added zdoc11 to qh-stat.h#ZZdef for !qh_KEEPstatistics [K. Ford]
- enhanced qh_initqhull_globals() test of qh_RANDOMint and qh_RANDOMmax
- added debugging option to always return qh_RANDOMmax from qh_rand()
- fixed option 'Qr', qh_initialvertices(), to allow a broken qh_rand()
fixed option 'Qr', qh_nextfurthest(), to allow narrow hulls
Option 'Qr' simulates the random incremental algorithm for convex hulls
- added note that qh.num_outside includes coplanar points for narrow hulls
- added FAQ items for triangles/ridges of 3-d Delaunay triangulation[P. Kumar]
- added FAQ item about on-line processing with the Qhull library [O. Skare]
- changed name of option 'Error-roundoff' to 'Distance-roundoff'
------------
qhull 2.6 1998/12/30
- for the unbounded rays of the Voronoi diagram, use a large box [Schmidt]
e.g., 'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 | qhull v Fv' fails for point 0
while 'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 c G5 | qhull v Fv' is OK.
- fixed qh_new_qhull() to use outfile/errfile instead of stdout/stderr [Ford]
- clarified COPYING.txt for use in other programs [Archer]
- improved qh_readpoints() error message for incorrect point count.
- added FAQ item for closest triangle to a point [Sminchisescu & Heijting]
- added FAQ item for is a point outside of a facet [Beardsley]
- added FAQ item for visiting facets of the Delaunay triangulation [Heijting]
- added link to Erickson's Computational Geometry Software
- added link to Sharman's HTML version of the comp.graphics.algorithms FAQ
- added link to Owen's Meshing Research Corner
- added note to 'd' about quadratic size of 'rbox 100 l | qhull d' [Kumar]
- added 'about a point' to mentions of halfspace intersection
- added request to qh-code.htm to compute largest empty circle [Hase]
- the DOS window in Windows NT is better than the DOS window in Windows 95
- removed obsolete qh_findfacet() from qh-c.htm [Sminchisescu]
------------
qhull 2.6 1998/8/12
new and modified features
- rbox: added option Mn,m,r to generate a rotated lattice or mesh
- rbox: report error if more than one of 'l', 'x', 'L', 's', or 'M'
Qhull library changes
- added qh_new_qhull() to user.c for calling qhull() from a program [D. Zwick]
rewrote user_eg.c to use qh_new_qhull(). Added qh_QHpointer example.
- added qh_CLOCKtype 2 in user.h to call times() for CPU time [B. Hemkemeier]
- renamed set.c/set.h to avoid conflict with STL's set.h [G. van den Bergen]
can also use '#include <qhull/qhull_a.h>' for Qhull library
fixed errors
- fixed qh_init_B() to call qh_initqhull_mem() once only [D. Zwick]
This only effects Qhull library users of qh_QHpointer.
- fixed qh_mergecycle_all() to check for redundant vertices [J. Nagle]
e.g., 'rbox M3,4 64 | qhull Qc' should report 8 vertices & 48 coplanars
- fixed gmcoord initialization in qh_setfacetplane() for qh.RANDOMdist
- turn off qh.RANDOMdist during qh_printfacetheader()
- fixed error messages for unknown option flags
documentation changes
- added note to FAQ on the Voronoi diagram of cospherical points [H. Hase]
- added note to 'Qu' on furthest-site Delaunay triangulation via convex hull
- added note to 'QJ' about coplanar points on the convex hull of the input
- added note that 'o' and 'FN' list Voronoi regions in site id order [Arvind]
- added links to Fukuda's introduction to convex hulls, etc. [H. Hase]
- added .c and .h source files to web distribution and qh-c.htm [J. Sands]
- documented qh_ZEROdelaunay. Delaunay and Voronoi diagrams do not include
facets that are coplanar with the convex hull of the input sites.
modified code
- replaced computed minnorm in qh_sethyperplane_det with distance test
- removed 'qh rand_seed' since random number generator is independent of qhull
- dropt 'qhull-PPC.sit.bin' from the distribution (out-of-date) [M. Harris]
------------
qhull 2.5 1998/5/4
fixed errors
- removed zero-area Delaunay triangles and furthest-site triangles [I. Beichl]
Zero-area triangles occur for points coplanar with the input's convex hull.
- replaced qh.MINnorm with computed minnorm in qh_sethyperplane_det [J. Nagle]
qh.MINnorm was incorrect for the convex hull of the "teapot" example.
Qhull runs 0-20% slower in 3-d and 4-d.
- allow 'Qg' with furthest-site Delaunay triangulation (may be faster)
- removed extra space in definition of FOREACHmerge_() for Alpha cc [R. LeRoy]
- fixed innerouter type in qh_printvdiagram2 [does not effect code, R. Adams]
documentation changes
- to browse qh-c.htm, set MIME type of .c and .h files to text/html
- added example of 3-d Delaunay triangulation to q-faq.htm
- added Delaunay and Voronoi examples to qh-optv.htm
------------
qhull 2.5 1998/2/4
- added option 'v Fi' for separating hyperplanes of bounded Voronoi regions
- added option 'v Fo' for separating hyperplanes of unbounded Voronoi regions
- option 'Pp' turns off the warning, "initial hull is narrow"
- fixed partial, 3-d Voronoi diagrams (i.e., 'v Fv QVn Tc')
- fixed missing statistics in qh_allstat* [T. Johnson]
- rearranged qh_printvdiagram. Use qh_eachvoronoi to iterate Voronoi ridges.
- added qh_check_points to qh-math.c
qhull 2.5 1998/1/28
- added option 'Fv' to print the Voronoi diagram
- added rbox option 'x' to generate random points in a simplex
- added rbox option 'y' to generate a simplex and random points
- added rbox option 'On' to offset the output
- add unpacking instructions to README.txt
- updated discussion of forced output, 'Po'
- sorted the options alphabetically
- removed __STDC__ check from libqhull.h for VisualC++
- moved qh_markvoronoi from qh_printvoronoi and cleared facet->seen flags
- added facet->seen2 flag for 'Fv'
qhull 2.5 1998/1/16
- fixed initialization of qh.last_low on restart of 'd QJ'
- renamed qh_JOGGLEmax to qh_JOGGLEmaxincrease
- updated URL for Fukuda's cdd program
qhull 2.5 1998/1/12
New or modified features
- added option 'Fx' to print vertices by point id [G. Harris, T. McClendon]
in 2-d, the vertices are printed in counter-clockwise order
for Delaunay triangl., 'Fx' lists the extreme points of the input sites
- added option 'QJ' to randomly joggle input instead of merging facets
- added option 'TO file' to output results to a file. Needed for Windows95.
- added option 'TRn' to rerun Qhull n times. Use to collect joggle statistics
Corrections
- fixed 2-d facet orientation for 'i' and 'o' outputs
- for Mathematica 2.2 ('m') changed %10.8g to %16.8f [A. Zhaxybayev]
- fixed incorrect warning for 'QV0 Qg' in qh_initbuild [B. Wythoff]
- fixed unaccessible statistic if !qh_KEEPstatistics for Wnewvertexmax
- fixed overestimate of qh ONEmerge for point sets outside of
first quadrant and far from the origin
- fixed overestimate of 'Qbb' for point sets far from the origin
- fixed potential overestimate of qh DISTround under 'Qbb'
- fixed 'p' printing coplanar points of unselected facets
- fixed 'Ft' printing centrums unnecessarily in 2-d
Changes to documentation
- wrote internal design documentation (qh-c.htm)
- started frequently asked questions (qh-faq.htm)
- added a section on joggled input to qh-impre.htm
- added joggle example to qh-eg.htm (eg.15.joggle)
- changed q_eg to use 'QJ' instead of 'Q0' were appropriate
- added an example to each of the main options
- added examples to rbox.htm
- added examples to the synopsis
- added a reference to Mucke, et al ['96], Fast randomized point location ...
- added code for printing Delaunay triangles to qh-code.htm [A. Tsui]
- options 'Pdk' and 'PDk' do not drop on equality
Improvements to the code
- reviewed warning messages for Qhull options in qh_initflags
- added warning to 's' if premature exit from 'TCn' or 'TVn'
- 's' prints max distance above/below only if qh.MERGING
- reduced maxoutside in qh_check_bestdist/qh_check_points for 'Rn'
- in post-merging, rebuild centrums of large facets that become small
- lowered cutoff for coplanar facets for ischeckmax/qh_findbest
- removed qh_check_maxout for 'Wn Q0'
- reset tracing after 'TPn' adds point in 4-d and higher
Changes for the Qhull library
- changed qh_setdelaunay to call qh_scalelast if used with 'Qbb' or 'QJ'
Delaunay callers to qh_findbestfacet, qh_addpoint, or qh_findfacet_all
should always use qh_setdelaunay as in user_eg.c
- defined qh.outside_err to check points against a given epsilon [E. Voth]
- added header to user_eg.c to avoid its incorporation into qhull [C. Begnis]
- added qh_nearcoplanar() calls to user_eg.c
only needed if use 'QJ'
- expanded __STDC__ warning message in libqhull.h [C. Begnis]
- renamed qh maxmaxcoord to qh MAXabs_coord
- replaced qh MAXlowcoord with qh MAXabs_coord
- random seed ('QR-n') is reset in qh_initqhull_globals after testing
- replaced 'FO' options "_max-coord/_min-coord" with "_max-width"/qh.MAXwidth
Other changes to Qhull functions
- report error for !bestfacet in qh_findbest (it shouldn't happen) [H. Meuret]
- set newbest in qh_findbest only if bestfacet updated
- renamed facet parameter for qh_findbest
- added maxdist argument to qh_checkpoint
- moved 'FO' output after qh_partitionall
- separated qh_initbuild from qh_qhull
- reinitialize globals modified by qh_buildhull
- moved initialization of qh.GOODvertexp & qh.GOODpointp to qh_initbuild
- separated qh_nearcoplanar from qh_check_maxout
- separated qh_geomplanes from qh_printfacet2geom, etc.
- separated qh_freebuild from qh_freeqhull
- separated qh_outerinner from io.c to return outer and inner planes
- separated qh_distround and qh_detroundoff from qh_maxmin
------------
qhull 2.4 97/4/2
New or modified features
- made 'C-0' and 'Qx' default options. Use 'Q0' to not handle roundoff errors
- removed point-at-infinity from Delaunay/Voronoi.
you no longer need to use 'Qu PDk'
- added 'Qz' to add a point-at-infinity to Delaunay and Voronoi constructions
- added published version of qhull article in ACM Trans Math Software
- ported qhull to Windows95 under Visual C++ and Borland C++
- added 'Ft' for triangulation by adding the centrums of non-simplicial facets
- added 'Gt' to display 3-d Delaunay triangulations with a transparent hull
- changed definition of coplanar point in output to qh min_vertex (see 'Qc')
it was qh MAXcoplanar ('Un') [could make vertices non-coplanar]
- automatically set 'Qi' for options 'd Qc' and 'v Qc'.
- reworded summary ('s') for Delaunay/Voronoi/halfspace.
use 'Fs' and 'FS' for summary statistics.
- for summary 's' of Delaunay/Voronoi, display number of coplanars for facets
if none, display total number of coplanars (i.e., non-vertices)
- input comment is first non-numeric text (previously limited to header)
- added input warning if use 'Qbb' without 'd' or 'v'
- 'Q3' can not be followed with a numeric option
Corrections
- fixed qh_partitioncoplanar() to not drop interior points if 'Qi' is used
- fixed 'FP d' to report distance in point set instead of paraboloid
- fixed qh_findbest() to search all coplanar facets for qh_check_maxout()
Changes to documentation
- added example eg.17f.delaunay.3 to show a triangulation of cospherical sites
- split up qh-opt.htm into multiple pieces
- split off qh-code.htm for Qhull code
- renamed .html files to .htm for Windows95
- rewrote qh-optv.htm on Delaunay triangulation and Voronoi vertices
- added 'man' pages qhull.txt and rbox.txt. These list all the options
- removed 'txt' versions of html files
- added note to 'PDk' about avoiding a 'd' option immediately after a float
- under option 'd', display the triangulation with 'GrD3', not 'GnrD3'
Changes to the Qhull library
- added 'format' argument to qh_printfacetNvertex_nonsimplicial() in io.c
- removed C++ type errors [J. Stern, S. Marino]
- created SETelemt, SETfirstt, etc. for specifying data types.
- use SETelem,etc. for assignments.
- changed setT.maxsize to 'int' to prevent type conversion warnings
- changed FOREACH.. to a comma expression for better code and less warning
- changed qh.vertex_visit and .visit_id to unsigned int to prevent warnings
- changed clock() to qh_CPUclock (user.h)
- qh_init_B() and qh_readpoints() do not set qh.ATinfinity for Delaunay tri.
- qh_setvoronoi_all() sets upper Delaunay facets if qh.UPPERdelaunay is set
- qh_nearvertex() returns distance in dim-1 for qh.DELAUNAY
- removed MSDOS path from qhull_command. Spaces in Win95 tripped qh_setflags
- removed memory.h from qhull_a.h. memset,etc. should be in strings.h
- split qh_prompt into pieces for Visual C++
- added note to qh_addpoint that coordinates can not be deallocated
- added Baker '89 to constrained Delaunay diagrams under Enhancements
please let me know if you try this
- added request for unbounded Voronoi rays to Enhancements
please let me know if you try this
------------
qhull V2.3 96/6/5
- fixed total area of Delaunay triangulation. [A. Enge]
It should ignore facets on the upper-envelope.
- if 'd Qu FA', the total area is summed over the upper-Delaunay triangles
- fixed sign of area for Delaunay triangulations.
- fixed cdd input format for Delaunay triangulation. [A. Enge]
- for cdd input, allow feasible point for halfspaces.
- warning if cdd output format for centrums, halfspace intersections, or OFF.
- print '0' for area ('Fa') if area is not computed for a facet
- option 'QR-n' sets random number seed to n without rotating input
- fixed qh_findbest() to retest coplanar and flipped facets after a restart
- for 'd Qu Ts' collects angle statistics for upper Delaunay facets
Changes to the Qhull library
- expanded user_eg.c for incremental constructions and Delaunay triangulation
- added discussion of incremental construction to qh_man.html#library
- WARNING: The default value of qh ATinfinity was changed from True to False.
A new flag, qh UPPERdelaunay, was defined for 'Qu'.
Please set qh ATinfinity if you explicitly add the point "at-infinity"
Please set qh ATinfinity if you explicitly call qh_projectinput.
Please set qh UPPERdelaunay if you explicitly cleared qh ATinfinity.
Other users do not need to change their code.
Now you can build a Delaunay triangulation without creating a point
"at-infinity". This removes a potential, hard-to-understand error.
qh_readpoints sets qh ATinfinity for options 'd' or 'v' without 'Qu'.
qh_initB sets qh ATinfinity for qh PROJECTdelaunay w/o qh UPPERdelaunay.
qh_projectinput adds a point "at-infinity" only if qh ATinfinity is set.
- added qh_setdelaunay to geom2.c to project points to paraboloid
- added qh_findbestfacet() to poly2.c to replace qh_findfacet()
- removed procedure qh_findfacet(). It does not always work.
- removed NULL option for facet in qh_addpoint(). It does not always work.
- added noupper parameter to qh_findbest.
- added search of upperdelaunay facets to qh_findbest()
- allowed qh_findbest() to start with a flipped or upperdelaunay facet
- removed qh_nonupper() -- it is no longer needed
- allow space at end of options
- fixed qh_projectinput for furthest-site Delaunay (qh PROJECTdelaunay 'd Qu')
- added voids to procedure declarations with empty parameter lists
------------
qhull V2.3 96/3/25
- fixed missing qh_check_maxout when coplanar points and no merged facets.
- fixed qh_freeqhull/allmem (e.g., if qh_NOmem) [only custom code] [E. Voth]
- fixed qh_freeqhull to free qh interior_point [E. Voth]
- fixed main() to free all of memory if qh_NOmem. Include "mem.h" [E. Voth]
- reset f.newcycle link in qh_mergecycle_all [E. Voth]
- fixed false error if 'Tc', coplanar points, and a narrow hull
- turn off 'Rn' when computing statistics, checking code, or tracing code
- removed ={0} from global.c and stat.c to reduce compiler warnings
- changed Makefile dependences to $(HFILES) for all but unix.o, set.o, mem.o
- pulled out qh_printpointid and reordered qh_pointid [E. Voth]
- removed some compiler warnings
- moved 'FO' print of options to just before qh_buildhull
- changed 'FO' to list difference from -1 for _narrow-hull
------------
qhull V2.2 96/2/15
- detect narrow initial hulls (cosine of min angle < qh_MAXnarrow in user.h).
Write warning if cosine < qh_WARNnarrow in user.h. If narrow (qh NARROWhull),
partition coplanar points as outside points and delay coplanar test to end.
Needed for RBOX 1000 L100000 s G1e-6 t995127886 | QHULL Tv
See 'limitations' in qh-impre.html for further discussion.
- corrected some confusions between 'FV' and 'Fv' in qh-opt.html
- fixed initialization error for small Voronoi diagrams (e.g., [0,0], [1,0], [0,1]) [J. Velez]
- fixed bad return from qh_mindiff in geom2.c
- for initial hull, first process facet with furthest outside point (qh_furthestnext)
- added facet->notfurthest flag for recomputing furthest point
- added check for __STDC__ (needs ANSI C) [E. Voth]
- reduced warning messages from [E. Voth]. e[1] in setT still reports a warning.
- added a cube to the discussion of option 'v' (Voronoi) in qh-opt.html [J. Velez]
- added notes about adjacent vertices to "Calling Qhull" in qh-man.html [R. Lewis & J. Velez]
- added note about 'lines closer' when viewing 3-d Delaunay triangulations [P. Kallberg]
- added option 'Q9' to always process furthest of furthest outside points.
- removed option 'Pp' from q_eg and qh-eg.html.
------------
qhull V2.2 95/12/28
- added option 'Qbb' to scale the last coordinate to [0,m] (max prev coord).
This reduces roundoff errors for Delaunay triangulations with integer coordinates.
- changed option 'Qu d' to print out the furthest-site Delaunay triangulation
Use options 'Qu d PD2' to compute the normal 2-d Delaunay triangulation without
the point at infinity.
- added notes to the documentation of option 'd'
- added notes to limitations of how Qhull handles imprecision
- added warning if options 'FP', 'Fc', or 'Gp' without option 'Qc' or 'Qi'
- added note to options 'PDk:n' and 'Pdk:n' that closest facet is returned if none match
- added check that 'Qbk' and 'QBk' does not invert paraboloid for 'd'
- added notes that qh_findfacet and qh_addpoint require lifted points for Delaunay triangulations
- fixed 'rbox s 5000 W1e-13 D2 | qhull d Qcu C-0 Qbb'
- fixed option 'QbB' (qh SCALEpoints was not set)
- fixed minor confusion between 'Gc' (print centrums) and 'Gp' (print points)
- rewrote qh_findbestnew for upper convex hull, Delaunay facets
- changed option name for 'Gp' from 'Gcoplanar' to 'Gpoints'
- changed "nearest" facet for 'Pdk' to threshold - normal
- reworked qh GOODclosest for 'Qg'
- added note that 'Qg' does not always work
- recorded option 'C-0' as "_zero-merge" in option 'FO'
- refined qh DISTround in qh_maxmin/geom2.c for Delaunay triangulations
qhull V2.2 95/12/4
- Version 2.2 fixes an important bug in computing Delaunay triangulations
and convex hulls with edges sharper than ninety degrees. The problem
occurs when processing a point at a sharp edge. A directed search can
not be used for partitioning because one side may hide facets from the
other side. The new lens-shaped distribution for rbox demonstrates the
problem. For example, 'rbox 100 L3 G0.5 s | qhull Tv' fails for Version 2.1.
O. Schramm found the bug when computing the Delaunay triangulation of points
near an outside edge.
I rewrote qh_findbest and related functions. Qh_findbest
uses an exhaustive test for sharp edges (qh_findbest_sharp).
Qh_findbest avoids the upper convex hull of Delaunay triangulations.
Options 'd' and 'v' no longer assign coplanar points to the upper convex hull.
Qh_check_maxout tests near-inside points. It ignores fully inside points.
When done, it removes near-inside points from the coplanar sets.
If you use qh_addpoint or qh_findbest, please review the function headers.
They do not work for lens-shaped hulls for arbitrary facets. They do work for
Delaunay triangulations.
Changes to options for V2.2
- added 'Qu' for computing the furthest-site Delaunay triangulation (upper hull)
and furthest-site Voronoi vertices.
- added 'FP' to print nearest vertex for coplanar points
- added coplanar count to 'Fs' and 's'
- added number of similar points to summary for Delaunay/Voronoi
- Option 'Qc' is no longer necessary when merging.
- 'o' format for Voronoi vertices ('v') generates "0" lines for similar points
- 'QRn' for Delaunay ('d' or 'v') now rotates about the Z axis (see qh_init_B).
Otherwise Qhull does not identify the upper hull
- removed option 'Qa' for "all points outside". In V2.1 it was automatically
set for 'd'. Even though it was a bad idea, it revealed the above bug.
- for option list ('FO'), added version, values for one-merge, maxpos, maxneg,
and near-inside, and flags for zero-centrum
- optimized 'C-0' and 'Qx'. These options ("zero-centrum") test vertices
instead of centrums for adjacent simplicial facets.
- if 'Tv', report number of points that are not verified due to qh_findbest
- Option 'Q8' ignores near-inside points.
rbox 95/12/3
- added lens distribution ('Ln') It may be used with 's', 'r', 'Wn', and 'Gn'
- removed default point count except for the test case, 'Dn'
- divided main() of rbox.c into sections
Documentation changes for V2.2
- added examples for lens distribution and furthest-site Delaunay triangulation
and renumbered the examples for q_eg
- described facet orientation in 'data structure' section [P. Soikkonen]
- added notes to qh-man.html/"What to do if something goes wrong"
- added note about using 'Tv' to verify the results [O. Schramm]
- expanded definition of f_r in Performance section [S. Grundmann]
- noted that Geomview display of a Voronoi diagram adds extra edges
for unbounded Voronoi cells
- rewrote error "convexity constraints may be too strong" [D. Newland]
- added limitations section to "Imprecision in Qhull"
- added note about zero-area facets to 'Imprecise convex hulls' in qh-impre.html
- added note to 'Qi' that it does not retain coplanar points
- added note that option 'Q5' may be used if outer planes are not needed
- added note to README.txt about Irix 5.1 [C. Goudeseune]
- added code fragment for visiting Voronoi vertices to "Calling Qhull" [M. Downes]
- added note about qh_addpoint() to "Calling Qhull" [M. Downes]
Errors fixed for V2.2
- use qh_sethyperplane_gauss if 3-d or 4-d norm is less than qh MINnorm
- count Zcentrumtests if qh_NOstat
- reversed sign convention for qh_sethyperplane_gauss
it was opposite to qh_sethyperplane_det
this effects qh_determinant and qh_detsimplex
- fixed error in qh_findgood_all with multiple restrictions, e.g., 'QVn Pdk'
- fixed call to qh_clearcenters for qh_produce_output
- in qh_errexit, report p0 if last furthest point
Changes for users of the Qhull library
- user code needs to define qh_version (see user_eg.c)
- merged initialization code into qh_init_A and qh_init_B [M. Mazzario]
old code works as before.
qh_initflags also sets qh qhull_command for qh_initthresholds
redid initialization for user_eg.c
- simplified user_eg.c. It computes the convex hull of a cube.
- added qh_setvoronoi_all in poly2.c to compute Voronoi centers
added related note to call_qhull
- added qh_findfacet to use in place of qh_findbest
- added qh_nearvertex to return nearest vertex in facet to point
- redid notes on multiple, concurrent calls in call_qhull/user.c
- changed BoolT to unsigned int (prevent implicit enum conversion warnings)
- added upperdelaunay to facetT. It indicates a facet of the upper convex hull.
- converted qhull-PPC.sit for CodeWarrior 7
Code changes for V2.2
- simplified calls to setjmp() for Cray J916 [Salazar & Velez]
- replaced fprintf(fp,string) with fputs in io.c
- 'qh num_coplanar' removed (too expensive and not used).
- added numcoplanars to qh_countfacets()
- added min norm to qh_normalize2(). qh_normalize() wasn't changed
- removed type casts from qh_point and qh_pointid [Salazar & Velez]
- account for roundoff error in detecting upper convex hull (qh ANGLEround).
- post merging uses qh_findbestnew for partitioning
- qh_findbestnew for qh_partitioncoplanar goes to best facet
- 'Qm' always processes points above the upper hull of a Delaunay triangulation
- GOODvertex initialized with qh_findbestnew instead of qh_findbest
- for 'v', qh_facetcenter returns furthest-neighbor vertex if 'Qu'
- added test for qh feasible_point if use 'Fp' and qh_sethalfspace_all
- reviewed Sugihara's algorithm for topologically robust beneath-beyond
- on error, report if qhull in post-merging or has completed
- if tracing, option 'FO' and qhull command always printed
- added current furthest point ("during p%d") to 'T-1' events
- added 'TWn' tracing for vertices of new facets (qh_setfacetplane)
- added 'TWn' tracing for vertices in an output facet (qh_check_maxout)
- reorganized split between poly/poly2.c and geom/geom2.c
- reordered object files in Makefile
------------
qhull V2.1 95/9/25
- converted qhull.man to html format, many edits
- referenced Shewchuk's triangle program and Schneiders' Mesh Generation page
- added option 'Qa' to force all points outside
automatically set for "precise" Delaunay or Voronoi [Salazar & Velez]
it is turned off by merging, 'Wn', 'Qc' or 'Qi'
- added coplanar points to option 'FN'
- moved option 'FO' to include default precision options
- changed default random number generator to qh_rand in geom2.c (user.h)
other code changes
- fixed option comment Pdrop-facets-dim-less, Qbound-dim-low, QbBound-unit-box
- defined ptr_intT for converting 64-bit ptrs to 'unsigned long' [D. Bremner]
- defined setelemT to distinguish actual size from pointers [D. Bremner]
use either e[...].p or e[...].i (user-level code should use set.h macros)
- changed %x to %p in format statements for pointers [D. Bremner]
- added test of REALmax,etc. to qh_maxmin [H. Poulard]
- added type parameter to qh_memalloc_() macro for type conversion
- added type conversion to qh_memalloc() calls where missing
- added type conversion to calls into set.c that return void*
other documentation changes:
- new URLs for graphics images
- fixed comment for facetT.neighbors in libqhull.h [P. Soikkonen]
- changed recommendations for precision errors in qh_printhelp_degenerate()
- added recommendation for 'V0' (facet is visible if distance >= 0)
- added note about 'long double' to user.h [S. Grundmann]
- added note about zero area Delaunay triangles for the 'v' option
- added note about locating Delaunay triangles to option 'd' [A. Curtis]
- added note that coplanar vertices correspond to duplicate points for 'd'
- added note about option 'd' automatically setting 'PDk' (lower convex hull)
- added note about precision errors to option 'd' [many users]
- added note about qh_findbest() to the Qhull library section [L. Lai]
- 'make install' renames qhull.man to qhull.1 for Unix [M. Phillips]
- renamed README, etc. to *.txt to match WWW conventions [D. Cervone]
------------
qhull V2.1 7/10/95
- in 2-d, 'v o' lists the vertex at infinity in order [R. Critchlow]
- it used to always list the vertex at infinity ("0") first
- rewrote description of 'v' option (Voronoi vertices and 2-d diagrams)
- added 'PFn' for printing facets whose area is at least 'n' [D. Holland]
- prefixed 'Q',etc. to the 'Q',etc. options in the long help prompt
- fixed references to 'Fv' and 'FV' options under option 'Hn,n,n'
- updated reference to cdd, <ftp://ifor13.ethz.ch/pub/fukuda/cdd/>
- in set.c, added some missing type coercions for qhmem.tempstack
qhull V2.1 6/12/95
- replaced qhull.ps with qhull-2.ps (paper submitted to ACM TOMS)
- use BUFSIZ for setvbuf for Power Macintosh
- number of good facets printed if QVn, QGn, Pd, or PD
- added Makefile for Borland C++ 4.02 with Win32 [D. Zwick]
- added note to Enhancements section of qhull.1 about constrained
Delaunay triangulations [T. Rasanen]
qhull V2.1 6/7/95
- fixed qh_facetarea_simplex() for non-simplicial facets [L. Schramm]
- fixed cast in qh_point and qh_pointid for 64-bit architectures
- fixed URL for Amenta's list of computational geometry software
- fixed cast in qh_meminitbuffers for qhmem.freelists
- added test for !qh half_space in qh readpoints
- clarified options for qh_printhelp_singular()
- discussed non-simplicial facet area under option 'Fa' in qhull.1
qhull V2.1 6/3/95
- home page for Qhull and new descriptions for the Qhull examples
http://www.qhull.org
- changed SIOUX buffering for Power Macintosh. It runs fast now.
added a project file for Metrowerk's C
- note in README about compiling qhull on the PC
qhull V2.1 beta 5/15/95
======= main changes ========
- added halfspace intersection ('Hn,n,n')
- facet merging is better, especially for high dimensions
- added 'Qx' for exact merges of coplanar points and precision faults
- facet merging is faster, especially for high dimensions.
e.g., convex hull of the 8-d hypercube is seven times faster
- added 'F' output formats for printing each aspect of the convex hull
- format 'Fa' computes facet areas, total area, and total volume
- format 'FO' writes a descriptive list of selected options to stderr
- moved all customization options to user.h
- changed the default precision to 'double' since it's needed for Delaunay.
using 'float' is faster and takes less space (REALfloat in user.h)
- option 'Qm' is no longer important for facet merging
- removed need for 'Qs' by selecting initial simplex with pos. determinants
- renamed 'Qv' to 'Q7' since virtual memory does not work well for qhull
- Qhull is available for the Power Mac (no graphical output)
====== other new and modified options ===========
- changed default MINvisible ('Vn') to a multiple of premerge_centrum ('C-n')
- added 'Un' option to set width of facet for coplanar points.
This replaces the previous rules for determining coplanar points.
- changed default MINoutside ('Wn') to twice MINvisible ('Vn')
- Geomview output adjusts point radii for MINvisible 'Vn'
- the input format allows the number of points to precede the dimension
- options 'v' 'd' 'FAn' and 'FMn' record good facets ('Pg')
- added 'Fd' and 'FD' options for homogeneous coordinates in cdd format
- in rbox, added 'h' flag to generate homogeneous coordinates in cdd format
- option 'PAn' prints out the n facets with the largest area
- option 'PMn' prints out the n facets with the most merges
- option 'Po' under tracing ('Tn') no longer tries to write erroneous facets
- option 'TCn' only prints the old 'visible' facets for 'f'
- 'TFn' reports intermediate results when post-merging
- option 'Ts' with option 'TFn' prints intermediate statistics
- the message for 'Tv' reports if it is checking outer planes
- 'Tz' sends stderr output to stdout
- added 'Q1' to ignore angle when sorting merges (merges are worse)
- added 'Q2' to not perform merges in independent sets (merges are worse)
- added 'Q3' to not remove redundant vertices (faster)
- added 'Q4' to avoid merges of old facets into new facets (does worse)
- added 'Q5' to skip qh_check_maxout (faster, but less accurate)
- added 'Q6' to skip pre-merge of concave and coplanar facets
- added 'Qv' for testing vertex neighbors for convexity (needs merge option)
- added warning if mix Geomview output with other outputs ('Po' turns off)
- options 'o v' for 3-d and higher sort the Voronoi vertices by index
======= documentation =======
- rewrote the introduction and precision sections
- added a section on performance
- added an example on halfspace intersection
- installed examples of Qhull in
<http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/>
======= Makefile, user.h, and messages =======
- Makefile calls ./qhull, ./rbox, and prints short prompt for qhull
- added new statistics, e.g., for buildhull
- changed default qh_RANDOMtype to RAND_MAX with rand()
- added comment about numeric overflow to printhelp_singular
- reorganized the code to improve locality of reference
- option in mem.h (qh_NOmem) to turn off memory management in qhull
- option in user.h (qh_NOtrace) to turn off tracing in qhull
- option in user.h (qh_NOmerge) to turn off merging in qhull.
- use this instead of redefining qh_merge_nonconvex in user.c
- simplified user_eg.c. See qh_call_qhull() in user.c for the full version
======== bug fixes ============
- fixed error in number of points for 'rbox 100 r' (odd distribution)
- fixed performance error in qh_degen_redundant_neighbors
- qh_partitionpoint now sets facet->maxoutside for first outside point
- fixed performance error in partitioning when merging a large, regular cone
- removed memory leak in qh_appendmergeset
- removed double free of qh line under errors in qh_readinput()
- forcing output on error ('Po') fixed for options 'n' 'o' 'i' 's'
- fixed optimization error on HP machines [fprintf(... *p++)]
======== changes to libqhull.h for user code =======
- qh_collectstatistics and qh_printstatistics removed from libqhull.h.
should use qh_printallstatistics instead
- qh_findbest uses boolT for newfacets
- added qh_findbestnew for non-simplicial facets. qh_findbest is
too slow in this case since it needs to look at many nearly coplanar
facets.
- renamed qh_voronoi/qh_centrum to qh_ASvoronoi, qh_AScentrum
- changed facet->id to 32-bits, added new flags for merging
- added facet->f for facet pointers while merging and for facet area
- added dfacet/dvertex for printing facets/vertices while debugging
- added qh_produce_output and qh_printsummary
======== changes to code ==========
- moved qh_setfacetplane from qh_makenewfacets to qh_makenewplanes
- added qh_setfree2, qh_setcompact, and qh_setduplicate to set.c
- qh_findgooddist returns list of visible facets instead of setting global
- in qh_check_maxout, inside points may be added to coplanar list.
- qh_findbestnew used for qh_partitionall. It is faster.
- in qh_findbest, changed searchdist to MINvisible+max_outside+DISTround.
MINvisible is the default MAXcoplanar.
- cleaned up list management via qh_resetlists
- uses facet->dupridge to indicate duplicated ridges instead of ->seen
- qh_buildtracing records CPU time relative to qh hulltime instead of 0
========== changes to merging =======
- many performance improvements, especially in high-d.
- when merging, qh_findbest and qh_findbestnew stops search at qh_DISToutside
- vertex neighbors delayed until first merge
- post merges reported every TFn/2 merges
- vertex merging turned off in 7-d and higher (lots of work, no benefit).
vertex merging moved to qh_qhull_postmerging in 6-d.
- replaced qh min_vertex with MAXcoplanar for determining coplanarity
- pick closest facets to merge in duplicate ridge instead of flip/flip
(see qh_matchduplicates in poly2.c)
- optimize merge of simplex into a facet
- optimize merge of a "samecycle" of facets into a coplanar horizon facet
- cleaned up qh_forcedmerges/qh_flippedmerges and removed facet->newmerge
- rewrote qh_merge_degenredundant with separate queue
- qh_facetdegen replaced by facet->degenredun
- flipped neighbors no longer merged in preference to flip/non-flip pairs
- removed angle argument from qh_merge_degenredundant and qh_mergefacet
only used for tracing
- getmergeset_initial had extra test of neighbor->simplicial
- ridge->nonconvex is now set on only one ridge between non-convex facets
- moved centrum deletion to qh_updatetested
- qh_isnewmerge(facet) changed to facet->newmerge (removed NEWmerges)
- qh_findbestneighbor reports correct distance even if testcentrum
- added hull_dim factor to qh_BESTcentrum
- removed horizon preference in qh_merge_nonconvex (qh AVOIDold)
- facet->keepcentrum if qh WIDEfacet or qh_MAXnewcentrum extra vertices
------------
qhull V2.02 1/25/95
- rbox 'z' prints integer coordinates, use 'Bn' to change range
- fixed rare bug in qh_check_maxout when qh_bestfacet returns NULL
- fixed performance bug in findbestneighbor, should be + BESTnonconvex
- renamed 'notgood' flag in 'f' option to 'notG' flag (caused confusion)
- changed qh.hulltime to (unsigned) to prevent negative CPU times
- added random perturbations to qh_getangle under the 'Rn' option
- reviewed the documentation and enhancement list
- added discussion of how to intersect halfspaces using qhull
- replaced expression that caused incorrect code under an old version of gcc
- added buffer after qh.errexit in case 'jmp_buf' has the wrong size
- rewrote qh_printhelp_singular for lower-dimensional inputs
- rewrote qh_printhelp_degenerate
- added options for qh_RANDOMint in qhull_a.h
- changed time format for 'TFn' to %02d
------------
qhull V2.01 6/20/94
- fixed bug in qh_matchnewfacets that occured when memory alignment makes
facet->neighbors larger than necessary.
- fixed bug in computing worst-case simplicial merge of angle coplanar
facets (ONEmerge). This decreases (...x) in printsummary.
qhull V2.01 6/17/94
- added recommendation for 'Qcm' to documentation and help prompts
- added an input warning to qh_check_points ('Tv') if coplanars and no 'Qc'
- qh_partitionpoint: always counts coplanar partitions (Zcoplanarpart)
- rewrote qh_printhelp_degenerate to emphasize option 'C-0'
- For Geomview output, roundoff is not needed when printing the inner and
outer planes. This improves Geomview output for the 'Rn' option.
- For Geomview output without coplanar points or vertices, qh_GEOMepislon
is not needed. This removes the edge gap when displaying a Voronoi cell.
- For Geomview output 'Gp', direct vertices to the interior point
instead of the arithmetic center of the displayed vertices.
qhull V2.01 6/11/94
- if pre-merge, 'Qf' is automatically set. Otherwise an outside point may
be dropt by qh_findbest(). This slows down partitioning.
- always use 'Qc' if merging and all facet->maxoutside's must be right.
Otherwise distributions with many coplanar points may occassionally
miss a coplanar point for a facet. This is because qh_findbest, when
called by qh_check_maxout, can become stuck at a local maximum if
the search is started at an arbitrary facet. With 'Qc', the search
is started from a coplanar facet. For example,
rbox 1000 W8e-6 t | qhull C-0 Tv
will (rarely) report that a facet->minoutside is incorrect
- option 'Pp' turns off "Verifying" message for 'Tv'
- added qh_copynonconvex to qh_renameridgevertex (fixes rare error)
- 'rbox tn' sets random seed to n
- 'rbox t' reports random seed in comment line
- qh_errexit reports rbox_command | qhull_command and 'QR' random seed
- added additional tracing to bestdist and setfacetplane
- in qh_checkconvex, need to test coplanar against 0 instead of -DISTround
- in qh_checkconvex, always test centrums if merging. The opposite
vertex of a simplicial facet may be coplanar since a vertex of
a simplicial facet may be above the facet's hyperplane.
- fixed error handling in qh_checkconvex when merging
- in qh_printsummary, one merge ratio not printed if less than 'Wn'
- documented that 'Tv' verifies all facet->maxoutside
qhull V2.01 6/2/94
- 's' prints summary to stderr
- multiple output formats printed in order to stdout
- added statistic for worst-case distance for merging simplicial facets
can not hope for a better "max distance above/below facet"
print factor for "max distance.."/"merge simplicial" in printsummary
- fixed error in scaling input with min/max reversed ('Qb0:1B0:-1')
- fixed error in scaling if project & Delaunay & scale ('d Qb0:0B1:0b2:0')
- user_eg.c: qh_delpoint removed since it does not always work
- user_eg.c now works for either convex hull or Delaunay triangulation
- added PROJECTdelaunay for Delaunay triangulations and Voronoi diagrams
with libqhull.a and user_eg.c
- user_eg.c: if project or scale input, need to copy points
- user_eg.c: default just defines main, added fprintf's for qh_errprint etc.
- qh_gausselim: a 0 pivot no longer zeros the rest of the array,
need the remaining elements for area computation
- qh_qhull: restore cos_max, centrum_radius at end of POSTmerging
- qh_checkflipped with !allerror is >=0.0 instead of >0.0
- removed -Wall from gcc due to unnecesssary "warning: implicit declaration"
- renamed 'new' variables and fields to allow compilation by g++
- added README notes on C++, and "size isn't known"
- updated manual on 'Qg' with coplanar facets and no merging ('rbox c D7')
'Qg Pg' and 'Pg' produce different results because of precision problems
------------
Converting from qhull 1.01 to qhull 2.00
- 'qhull An' is now 'qhull Wn'
option 'Wn Po' is faster but it doesn't check coplanars
- 'qhull g' is now 'qhull G', and the output formats are different
- 'qhull c' is now 'qhull Tc'
- 'qhull f' is now 'qhull Qf'
- 'qhull o' is now 'qhull Po'
- 'qhull b' is now always done
- qhull and rbox now use floats, change REALfloat in libqhull.h for doubles
- qhull 2.00 fixes several initialization errors and performanace errors
e.g., "singular input" on data with lots of 0 coordinates
- 'rbox b' is now 'rbox c G0.48'
- all rbox distributions are now scaled to a 0.5 box (use 'Bn' to change)
- rbox now adds a comment line. This may be removed by 'rbox n'
- 'rbox r s Z G' no longer includes the positive pole
- no changes to the Macintosh version
qhull V2.00 5/23/94
- if force output ('Po'), facet->maxoutside= 'Wn' since coplanars not updated
convexity checked if precision problems or verify ('Tv')
- if merging, new facets always checked for flipped orientation
- a facet is visible (findhorizon) under 'Qm' if distance > max_vertex
- if using 'Qm' then min. outside is max_vertex instead of max_outside
- default is random()/srandom() in qhull_a.h, checked in initqhull_globals
- created internal strtod since strtod may skip spacing after number
- removed lower bound (1.0) for qh maxmaxcoord
- divzero needs to handle 0/0 and large/small
- decreased size of precise vertices
- need to initialize qh MINdenom_1 for scalepoints
- added factor of qh maxmaxcoord into DISTround (needed for offset)
- 'Rn' perturbs distance computations by random +/-n
- check_points needs an extra DISTround to get from precise point to computed
- rewrote some of the IMPRECISION section in qhull.man
- added the input format to the qhull prompt
- moved include files to qhull_a.h since some compilers do not use float.h
- added qhull.1 and rbox.1 since SGI does not ship nroff
- reduced cutoff for printpointvect
- use time for qhull random seed only if QR0 or QR-1
- radius of vertices and coplanar points determined by pre-merge values
qhull V2.00 5/12/94
- facet2point (io.c) used vertex0 instead of vertex1
- can't print visible facets after cone is attached
- shouldn't check output after STOPcone (TCn)
- statistic 'Wminvertex' and 'Wmaxoutside' only if MERGING or APPROXhull
- 'make doc' uses lineprinter format for paging
- warning if Gpv in 4-d
qhull V2.b05 5/9/94
- decreased size of precise vertices
- precise facets in 2-d print hyperplanes
- accounted for GOODpoint in printsummary
- added IMPRECISION section to qhull.man
- 'Qg' does work in 7-d unless there's many coplanar facets
diff --git a/src/libqhull/DEPRECATED.txt b/src/libqhull/DEPRECATED.txt
index 11fdb62..9d08286 100644
--- a/src/libqhull/DEPRECATED.txt
+++ b/src/libqhull/DEPRECATED.txt
@@ -1,13 +1,33 @@
qhull/src/libqhull
- This directory contains the deprecated qh_qh global configuration of qhull
+ This directory contains the non-reentrant version of qhull, libqhull.
- It will be maintained at least until January 2015.
+ New code should use the reentrant version of qhull, libqhull_r.
+ It allows multiple instances of qhull to run at the same time. On
+ modern architectures, it is nearly as fast as libqhull.
- Except for qhull, the qhull executables will continue to build with libqhull.
+ Qhull programs may be built with either library. Each program has a
+ reentrant version (e.g., qconvex_r.c) and a non-reentrant
+ version (qconvex.c). The programs, rbox, qconvex, qdelaunay, qhalf,
+ and qvoronoi, are built with libqhull. The qhull program is built
+ with libqhull_r.
+
+ Qhull's C++ interface requires libqhull_r. If you previously used the
+ C++ interface, you will need to update your code. See Changes.txt for
+ suggestions.
+
+ The C code in libqhull looks unusual because of the 'qh' macro. The 'qh'
+ macro controls access to Qhull's global data structure, qhT. If
+ 'qh_QHpointer' is defined, 'qh' is 'qh_qh->' and 'qh_qh' is defined as
+ 'qhT *qh_qh', otherwise 'qh' is 'qh_qh.' and 'qh_qh' is defined as
+ 'qhT qh_qh'.
+
+ libqhull will be supported indefinitely. The qh_QHpointer variation
+ of libqhull will be not be retested each release. It is replaced by
+ libqhull_r.
+
+
- See qhull/src/libqhullr for the reentrant version of qhull. On modern
- architectures, it is as fast or faster than the global configuration.
diff --git a/src/libqhull/Makefile b/src/libqhull/Makefile
index 7b75649..e7b4d70 100644
--- a/src/libqhull/Makefile
+++ b/src/libqhull/Makefile
@@ -1,186 +1,238 @@
-# Simple gcc Makefile for qhull and rbox (default gcc/g++)
+# Simple gcc Makefile for non-reentrant qhull and rbox (default gcc/g++)
#
# see README.txt
#
# Results
# qhull Computes convex hulls and related structures
-# qconvex, qdelaunay, qhalf, qvoronoi
+# qconvex , qdelaunay, qhalf, qvoronoi
# Specializations of qhull for each geometric structure
-# user_eg An example of using shared library qhull6_p (with qh_QHpointer)
-# user_eg2 An example of using shared library qhull (without qh_QHpointer)
-# testqset Standalone test of qset.c with mem.c
-# libqhullstatic.a Static library for qhull
+# rbox Input generator for qhull, qconvex, etc.
+# user_eg An example of using qhull (non-reentrant)
+# user_eg2 An example of using qhull (non-reentrant)
+# testqset Standalone test of non-reentrant qset.c with mem.c
+# libqhullstatic.a Static library for non-reentrant qhull
#
# Make targets
# make Produce all of the results
-# make qhull_all Produce qconvex, etc.
-# Links program sources into src/libqhull
+# make help Help message
+# make test Quck test of qhull, qconvex, etc.
# make qtest Quick test of qset, rbox, and qhull
# make doc Print documentation
# 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 clean Remove object files
# make cleanall Remove generated files
#
# BINDIR directory where to copy executables
-# DESTDIR destination directory
+# 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.a
#
# Do not replace tabs with spaces. Needed by 'make' for build rules
-# You may build the qhull programs without using a library
-# make qhullx
-
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, -O2 for optimization, -g for debugging
+#for Gnu's gcc compiler, -O3 for optimization, -g for debugging
+# -fPIC is no longer needed
CC = gcc
-CC_OPTS1 = -O2 -fPIC -ansi $(CC_WARNINGS)
+CC_OPTS1 = -O3 -ansi -I.. $(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
+#CC_OPTS1 = -Xc -v -fast -I..
# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
#CC = cc
-#CC_OPTS1 = -ansi -O2
+#CC_OPTS1 = -ansi -O2 -I..
# for Next cc compiler with fat executable
#CC = cc
-#CC_OPTS1 = -ansi -O2 -arch m68k -arch i386 -arch hppa
+#CC_OPTS1 = -ansi -O2 -I.. -arch m68k -arch i386 -arch hppa
# For loader, ld,
CC_OPTS2 = $(CC_OPTS1)
CXX_OPTS2 = $(CXX_OPTS1)
# Default targets for make
all: qhull_links qhull_all qtest
+help:
+ head -n 52 Makefile
+
clean:
rm -f *.o
# Delete linked files from other directories [qhull_links]
rm -f qconvex.c unix.c qdelaun.c qhalf.c qvoronoi.c rbox.c
- rm -f user_eg.c user_eg2.c testqset.c
+ rm -f user_eg.c user_eg2.c testqset.c
cleanall: clean
rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
rm -f core user_eg user_eg2 testqset libqhullstatic.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.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
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.o stat.o geom2.o poly2.o merge.o \
libqhull.o geom.o poly.o qset.o mem.o random.o
LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem.o userprintf.o io.o user.o
LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib.o userprintf_rbox.o
LIBQHULL_HDRS= user.h libqhull.h qhull_a.h geom.h \
io.h mem.h merge.h poly.h random.h \
qset.h stat.h
# CFILES ordered alphabetically after libqhull.c
CFILES= ../qhull/unix.c libqhull.c geom.c geom2.c global.c io.c \
mem.c merge.c poly.c poly2.c random.c rboxlib.c \
qset.c stat.c user.c usermem.c userprintf.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:
- [ -f qconvex.c ] || ln -s ../qconvex/qconvex.c
- [ -f qdelaun.c ] || ln -s ../qdelaunay/qdelaun.c
- [ -f qhalf.c ] || ln -s ../qhalf/qhalf.c
- [ -f qvoronoi.c ] || ln -s ../qvoronoi/qvoronoi.c
- [ -f qhull.c ] || ln -s ../qhull/unix.c
- [ -f rbox.c ] || ln -s ../rbox/rbox.c
- [ -f user_eg.c ] || ln -s ../user_eg/user_eg.c
- [ -f user_eg2.c ] || ln -s ../user_eg2/user_eg2.c
- [ -f testqset.c ] || ln -s ../testqset/testqset.c
+ # On MINSYS, 'ln -s' may create a copy instead of a symbolic link
+ [ -f qconvex.c ] || ln -s ../qconvex/qconvex.c
+ [ -f qdelaun.c ] || ln -s ../qdelaunay/qdelaun.c
+ [ -f qhalf.c ] || ln -s ../qhalf/qhalf.c
+ [ -f qvoronoi.c ] || ln -s ../qvoronoi/qvoronoi.c
+ [ -f rbox.c ] || ln -s ../rbox/rbox.c
+ [ -f testqset.c ] || ln -s ../testqset/testqset.c
+ [ -f unix.c ] || ln -s ../qhull/unix.c
+ [ -f user_eg.c ] || ln -s ../user_eg/user_eg.c
+ [ -f user_eg2.c ] || ln -s ../user_eg2/user_eg2.c
# compile qhull without using bin/libqhullstatic.a
qhull_all: qconvex.o qdelaun.o qhalf.o qvoronoi.o unix.o user_eg.o user_eg2.o rbox.o testqset.o $(LIBQHULLS_OBJS)
$(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex.o
$(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun.o
$(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf.o
$(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi.o
- $(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix.o
+ $(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix.o
$(CC) -o rbox $(CC_OPTS2) -lm rbox.o rboxlib.o random.o usermem.o userprintf_rbox.o
- $(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg.o
+ $(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg.o
$(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2.o usermem.o userprintf.o io.o
$(CC) -o testqset $(CC_OPTS2) -lm mem.o qset.o testqset.o
-ar -rs libqhullstatic.a $(LIBQHULLS_OBJS)
#libqhullstatic.a is not needed for qhull
#If 'ar -rs' fails try using 'ar -s' with 'ranlib'
#ranlib libqhullstatic.a
qtest:
+ @echo ============================================
+ @echo == make qtest ==============================
+ @echo ============================================
+ @echo -n "== "
+ @date
+ @echo
@echo Testing qset.c and mem.c with testqset
./testqset 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/libqhull/geom.c b/src/libqhull/geom.c
index 6b16f80..d425378 100644
--- a/src/libqhull/geom.c
+++ b/src/libqhull/geom.c
@@ -1,1234 +1,1234 @@
/*<html><pre> -<a href="qh-geom.htm"
>-------------------------------</a><a name="TOP">-</a>
geom.c
geometric routines of qhull
see qh-geom.htm and geom.h
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhull/geom.c#6 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/geom.c#7 $$Change: 1831 $
+ $DateTime: 2015/02/07 20:31:47 $$Author: bbarber $
infrequent code goes into geom2.c
*/
#include "qhull_a.h"
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="distplane">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="findbest">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="findbesthorizon">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="findbestnew">-</a>
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)
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 [?] ============ */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="backnormal">-</a>
qh_backnormal( rows, numrow, numcol, sign, normal, nearzero )
given an upper-triangular rows array and a sign,
solve for normal equation x using back substitution over rows U
returns:
normal= x
if will not be able to divzero() when normalized(qh.MINdenom_2 and qh.MINdenom_1_2),
if fails on last row
this means that the hyperplane intersects [0,..,1]
sets last coordinate of normal to sign
otherwise
sets tail of normal to [...,sign,0,...], i.e., solves for b= [0...0]
sets nearzero
notes:
assumes numrow == numcol-1
see Golub & van Loan 4.4-9 for back substitution
solves Ux=b where Ax=b and PA=LU
b= [0,...,0,sign or 0] (sign is either -1 or +1)
last row of A= [0,...,0,1]
1) Ly=Pb == y=b since P only permutes the 0's of b
design:
for each row from end
perform back substitution
if near zero
use qh_divzero for division
if zero divide and not last row
set tail of normal to 0
*/
void qh_backnormal(realT **rows, int numrow, int numcol, boolT sign,
coordT *normal, boolT *nearzero) {
int i, j;
coordT *normalp, *normal_tail, *ai, *ak;
realT diagonal;
boolT waszero;
int zerocol= -1;
normalp= normal + numcol - 1;
*normalp--= (sign ? -1.0 : 1.0);
for (i=numrow; i--; ) {
*normalp= 0.0;
ai= rows[i] + i + 1;
ak= normalp+1;
for (j=i+1; j < numcol; j++)
*normalp -= *ai++ * *ak++;
diagonal= (rows[i])[i];
if (fabs_(diagonal) > qh MINdenom_2)
*(normalp--) /= diagonal;
else {
waszero= False;
*normalp= qh_divzero(*normalp, diagonal, qh MINdenom_1_2, &waszero);
if (waszero) {
zerocol= i;
*(normalp--)= (sign ? -1.0 : 1.0);
for (normal_tail= normalp+2; normal_tail < normal + numcol; normal_tail++)
*normal_tail= 0.0;
}else
normalp--;
}
}
if (zerocol != -1) {
zzinc_(Zback0);
*nearzero= True;
trace4((qh ferr, 4005, "qh_backnormal: zero diagonal at column %d.\n", i));
qh_precision("zero diagonal on back substitution");
}
} /* backnormal */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="gausselim">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="getangle">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="getcenter">-</a>
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;
}
return(center);
} /* getcenter */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="getcentrum">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="getdistance">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="normalize">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="normalize2">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="projectpoint">-</a>
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 !qh_NOmem */
+ 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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="setfacetplane">-</a>
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 !qh_NOmem */
+ 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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="sethyperplane_det">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="sethyperplane_gauss">-</a>
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/libqhull/global.c b/src/libqhull/global.c
index f3f3114..88053fd 100644
--- a/src/libqhull/global.c
+++ b/src/libqhull/global.c
@@ -1,2129 +1,2187 @@
/*<html><pre> -<a href="qh-globa.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/global.c#18 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/global.c#23 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_a.h"
/*========= qh definition -- globals defined in libqhull.h =======================*/
-int qhull_inuse= 0; /* not used */
-
#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
/*-<a href ="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh_version">-</a>
qh_version
version string by year and date
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
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 = "2012.1 2012/02/18";
+const char *qh_version = "2015.0.2 2015/08/30";
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="appendprint">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="checkflags">-</a>
qh_checkflags( commandStr, hiddenFlags )
errors if commandStr contains hiddenFlags
- hiddenFlags starts and ends with a space and is space deliminated (checked)
+ 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="qh_clear_outputflags">-</a>
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_ouputflags */
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="clock">-</a>
qh_clock()
return user CPU time in 100ths (qh_SECtick)
only defined for qh_CLOCKtype == 2
notes:
use first value to determine time 0
from Stevens '92 8.15
*/
unsigned long qh_clock(void) {
#if (qh_CLOCKtype == 2)
struct tms time;
static long clktck; /* initialized first call */
double ratio, cpu;
unsigned long ticks;
if (!clktck) {
if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freebuffers">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freebuild">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freeqhull">-</a>
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
}
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freeqhull2">-</a>
qh_freeqhull2( allmem )
free global memory
if !allmem,
does not free short memory (freed by qh_memfreeshort)
notes:
sets qh.NOerrexit in case caller forgets to
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) {
trace1((qh ferr, 1006, "qh_freeqhull2: free global memory\n"));
qh NOerrexit= True; /* no more setjmp since called at exit and ~QhullQh */
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_A">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_B">-</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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_qhull_command">-</a>
qh_init_qhull_command( argc, argv )
build qh.qhull_command from argc/argv
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initflags">-</a>
qh_initflags( commandStr )
set flags and initialized constants from commandStr
returns:
sets qh.qhull_command to command if needed
notes:
ignores first word (e.g., "qhull d")
use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
see:
qh_initthresholds() continues processing of 'Pdn' and 'PDn'
'prompt' in unix.c for documentation
design:
- for each space-deliminated option group
+ for each space-delimited option group
if top-level option
check syntax
- append approriate option to option string
+ append appropriate option to option string
set appropriate global variable or append printFormat to print options
else
for each sub-option
check syntax
- append approriate option to option string
+ 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){
+ qh_fprintf(qh ferr, 6245, "qhull error: qh.NOerrexit not cleared after setjmp() and before qh_initflags(). Exiting with error.");
+ 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;
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 (!freopen(filename, "w", stdout)) {
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_buffers">-</a>
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_ouputflags */
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_globals">-</a>
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 != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
+ }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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_mem">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_outputflags">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_start">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_start2">-</a>
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= -1;
+ 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= -1; /* recompile or use 'TPn' */
+ 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 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initthresholds">-</a>
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 */
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="lib_check">-</a>
+
+ qh_lib_check( isQHpointer, 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 libraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
+ boolT iserror= False;
+
+ if (libraryType==0 && 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 (libraryType==1 && !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 (libraryType==2) {
+ qh_fprintf(stderr, 6248, "qh_lib_check: Incorrect qhull library called. Caller uses reentrant Qhull while library is non-reentrant.");
+ 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_version);
+ }else{
+ qh_fprintf(stderr, 6256, "qh_lib_check: Cannot continue. Library '%s' uses a static qhT (e.g., libqhull.so)\n", qh_version);
+ }
+ qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
+ }
+} /* lib_check */
+
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="option">-</a>
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
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="restore_qhull">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="save_qhull">-</a>
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/libqhull/index.htm b/src/libqhull/index.htm
index 15f84b8..321222a 100644
--- a/src/libqhull/index.htm
+++ b/src/libqhull/index.htm
@@ -1,248 +1,247 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>Qhull functions, macros, and data structures</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code</a><br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
<hr>
<!-- Main text of document. -->
<h1>Qhull functions, macros, and data structures</h1>
<blockquote>
<p>The following sections provide an overview and index to
Qhull's functions, macros, and data structures. Each
section starts with an introduction. If you use Opera, the source code links back to this documentation.
See also <a href=../../html/qh-code.htm#library>Calling
Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
<p>Qhull uses the following conventions:</p>
<blockquote>
<ul>
<li>in code, global variables start with &quot;qh &quot;
<li>in documentation, global variables start with 'qh.'
<li>constants start with an upper case word
<li>important globals include an '_'
<li>functions, macros, and constants start with &quot;qh_&quot;</li>
<li>data types end in &quot;T&quot;</li>
<li>macros with arguments end in &quot;_&quot;</li>
<li>iterators are macros that use local variables</li>
<li>iterators for sets start with &quot;FOREACH&quot;</li>
<li>iterators for lists start with &quot;FORALL&quot;</li>
<li>qhull options are in single quotes (e.g., 'Pdn')</li>
<li>lists are sorted alphabetically</li>
<li>preprocessor directives on left margin for older compilers</li>
</ul>
</blockquote>
<p>
When reading the code, please note that the
global data structure, 'qh', is a macro. It
either expands to &quot;qh_qh.&quot; or to
&quot;qh_qh-&gt;&quot;. The later is used for
applications which run concurrent calls to qh_qhull().
<p>
When reading code with an editor, a search for
<i>&quot;procedure</i>
will locate the header of <i>qh_procedure</i>. A search for <i>* procedure</i>
will locate the tail of <i>qh_procedure</i>.
<p>A useful starting point is <a href="libqhull.h">libqhull.h</a>. It defines most
of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
determine the corresponding <a href="libqhull.h#qh_PRINT">qh_PRINT...</a> constant.
Search <a href="io.c">io.c</a> to learn how the print function is implemented.</p>
<p>If your web browser loads .c and .h files with an external application,
change the MIME type of .c and .h files to "text/html".
Opera does not always work since it treats '&lt;' characters as HTML tags.
<p>
Please report documentation and link errors
to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
</blockquote>
<p><b>Copyright &copy; 1997-2015 C.B. Barber</b></p>
<hr>
<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull files</a> </h2>
<blockquote>
<p>This sections lists the .c and .h files for Qhull. Please
refer to these files for detailed information.</p>
<blockquote>
<dl>
<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
platforms with <a href=http://www.cmake.org/>CMake</a>.
Qhull includes project files for Visual Studio and Qt.
</dd>
<dt>&nbsp;</dt>
<dt><a href="libqhull.h"><b>libqhull.h</b></a> </dt>
<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
Data structures are documented under <a href="qh-poly.htm">Poly</a>.
Global variables are documented under <a href="qh-globa.htm">Global</a>.
Other data structures and variables are documented under
<a href="qh-qhull.htm#TOC">Qhull</a> or <a href="qh-geom.htm"><b>Geom</b></a><b>.</b></dd>
<dt>&nbsp;</dt>
<dt><a href="qh-geom.htm"><b>Geom</b></a><b>, </b>
<a href="geom.h"><b>geom.h</b></a><b>, </b>
<a href="geom.c"><b>geom.c</b></a><b>, </b>
<a href="geom2.c"><b>geom2.c</b></a><b>, </b>
<a href="random.c"><b>random.c</b></a><b>, </b>
<a href="random.h"><b>random.h</b></a></dt>
<dd>Geometric routines. These routines implement mathematical
functions such as Gaussian elimination and geometric
routines needed for Qhull. Frequently used routines are
in <tt>geom.c</tt> while infrequent ones are in <tt>geom2.c</tt>.
</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-globa.htm"><b>Global</b></a><b>, </b>
<a href="global.c"><b>global.c</b></a><b>, </b>
<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
to store globally defined constants, lists, sets, and
variables.
<tt>global.c</tt> initializes and frees these
structures. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-io.htm"><b>Io</b></a><b>, </b><a href="io.h"><b>io.h</b></a><b>,
</b><a href="io.c"><b>io.c</b></a> </dt>
<dd>Input and output routines. Qhull provides a wide range of
input and output options.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-mem.htm"><b>Mem</b></a><b>, </b>
<a href="mem.h"><b>mem.h</b></a><b>, </b>
<a href="mem.c"><b>mem.c</b></a> </dt>
<dd>Memory routines. Qhull provides memory allocation and
deallocation. It uses quick-fit allocation.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-merge.htm"><b>Merge</b></a><b>, </b>
<a href="merge.h"><b>merge.h</b></a><b>, </b>
<a href="merge.c"><b>merge.c</b></a> </dt>
<dd>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.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-poly.htm"><b>Poly</b></a><b>, </b>
<a href="poly.h"><b>poly.h</b></a><b>, </b>
<a href="poly.c"><b>poly.c</b></a><b>, </b>
<a href="poly2.c"><b>poly2.c</b></a><b>, </b>
<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
<dd>Polyhedral routines. Qhull produces a polyhedron as a
list of facets with vertices, neighbors, ridges, and
geometric information. <tt>libqhull.h</tt> defines the main
data structures. Frequently used routines are in <tt>poly.c</tt>
while infrequent ones are in <tt>poly2.c</tt>.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-qhull.htm#TOC"><b>Qhull</b></a><b>, </b>
<a href="libqhull.c"><b>libqhull.c</b></a><b>, </b>
<a href="libqhull.h"><b>libqhull.h</b></a><b>, </b>
<a href="qhull_a.h"><b>qhull_a.h</b></a><b>, </b>
-<a href="../qhull/unix.c"><b>unix.c</b></a> <b>, </b>
+<a href="../qhullo/unix.c"><b>unix.c</b></a> <b>, </b>
<a href="../qconvex/qconvex.c"><b>qconvex.c</b></a> <b>, </b>
<a href="../qdelaunay/qdelaun.c"><b>qdelaun.c</b></a> <b>, </b>
<a href="../qhalf/qhalf.c"><b>qhalf.c</b></a> <b>, </b>
<a href="../qvoronoi/qvoronoi.c"><b>qvoronoi.c</b></a> </dt>
<dd>Top-level routines. The Quickhull algorithm is
implemented by <tt>libqhull.c</tt>. <tt>qhull_a.h</tt>
includes all header files. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-set.htm"><b>Set</b></a><b>, </b>
<a href="qset.h"><b>qset.h</b></a><b>, </b>
<a href="qset.c"><b>qset.c</b></a> </dt>
<dd>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. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-stat.htm"><b>Stat</b></a><b>, </b>
<a href="stat.h"><b>stat.h</b></a><b>, </b>
<a href="stat.c"><b>stat.c</b></a> </dt>
<dd>Statistical routines. Qhull maintains statistics about
its implementation. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-user.htm"><b>User</b></a><b>, </b>
<a href="user.h"><b>user.h</b></a><b>, </b>
<a href="user.c"><b>user.c</b></a><b>, </b>
<a href="../user_eg/user_eg.c"><b>user_eg.c</b></a><b>, </b>
<a href="../user_eg2/user_eg2.c"><b>user_eg2.c</b></a><b>, </b>
-<a href="../user_eg3/user_eg3.cpp"><b>user_eg3.cpp</b></a><b>, </b>
<a href="../libqhullcpp/qhull_interface.cpp#TOP"><b>qhull_interface.cpp</b></a></dt>
<dd>User-defined routines. Qhull allows the user to configure
the code with defined constants and specialized routines.
</dd>
</dl>
</blockquote>
</blockquote>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhull/io.c b/src/libqhull/io.c
index 9094794..db30f2a 100644
--- a/src/libqhull/io.c
+++ b/src/libqhull/io.c
@@ -1,4062 +1,4061 @@
/*<html><pre> -<a href="qh-io.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/io.c#6 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/io.c#8 $$Change: 1868 $
+ $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
*/
#include "qhull_a.h"
/*========= -functions in alphabetical order after qh_produce_output() =====*/
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="produce_output">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="qh_dfacet">-</a>
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;
}
}
} /* qh_dfacet */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="qh_dvertex">-</a>
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;
}
}
} /* qh_dvertex */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="compare_facetarea">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="compare_facetmerge">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="compare_facetvisit">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="compare_vertexpoint">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="copyfilename">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="countfacets">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="detvnorm">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="detvridge">-</a>
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(&centers, neighbor);
}else if (firstinf) {
firstinf= False;
qh_setappend(&centers, neighbor);
}
}
}
qsort(SETaddr_(centers, facetT), (size_t)qh_setsize(centers),
sizeof(facetT *), qh_compare_facetvisit);
qh_settempfree(&tricenters);
return centers;
} /* detvridge */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="detvridge3">-</a>
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(&centers, facet);
}else if (firstinf) {
firstinf= False;
qh_setappend(&centers, 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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="eachvoronoi">-</a>
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(&centers);
}
}
}
}
}
}
FOREACHneighbor_(atvertex)
neighbor->seen= False;
qh_settempfree(&tricenters);
return totridges;
} /* eachvoronoi */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="eachvoronoi_all">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="facet2point">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="facetvertices">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="geomplanes">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="markkeep">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="markvoronoi">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="order_vertexneighbors">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="prepare_output">-</a>
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);
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();
}
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printafacet">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printbegin">-</a>
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, -1);
+ qh_printpointid(qh fout, NULL, num, point, qh_IDunknown);
FOREACHpoint_(qh other_points)
- qh_printpointid(qh fout, NULL, num, point, -1);
+ 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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printcenter">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printcentrum">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printend">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printend4geom">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printextremes">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printextremes_2d">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printextremes_d">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet2geom">-</a>
qh_printfacet2geom( fp, facet, color )
print facet as part of a 2-d VECT for Geomview
notes:
assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
mindist is calculated within io.c. maxoutside is calculated elsewhere
so a DISTround error may have occured.
*/
void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]) {
pointT *point0, *point1;
realT mindist, innerplane, outerplane;
int k;
qh_facet2point(facet, &point0, &point1, &mindist);
qh_geomplanes(facet, &outerplane, &innerplane);
if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
qh_printfacet2geom_points(fp, point0, point1, facet, outerplane, color);
if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
for (k=3; k--; )
color[k]= 1.0 - color[k];
qh_printfacet2geom_points(fp, point0, point1, facet, innerplane, color);
}
qh_memfree(point1, qh normal_size);
qh_memfree(point0, qh normal_size);
} /* printfacet2geom */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet2geom_points">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet2math">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet3geom_nonsimplicial">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet3geom_points">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet3geom_simplicial">-</a>
qh_printfacet3geom_simplicial( )
print Geomview OFF for a 3-d simplicial facet.
notes:
may flip color
uses facet->visitid for intersections and ridges
assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
innerplane may be off by qh DISTround. Maxoutside is calculated elsewhere
so a DISTround error may have occured.
*/
void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
setT *points, *vertices;
vertexT *vertex, **vertexp, *vertexA, *vertexB;
facetT *neighbor, **neighborp;
realT outerplane, innerplane;
realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
int k;
qh_geomplanes(facet, &outerplane, &innerplane);
vertices= qh_facet3vertex(facet);
points= qh_settemp(qh TEMPsize);
FOREACHvertex_(vertices)
qh_setappend(&points, vertex->point);
if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
qh_printfacet3geom_points(fp, points, facet, outerplane, color);
if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
for (k=3; k--; )
color[k]= 1.0 - color[k];
qh_printfacet3geom_points(fp, points, facet, innerplane, color);
}
qh_settempfree(&points);
qh_settempfree(&vertices);
if ((qh DOintersections || qh PRINTridges)
&& (!facet->visible || !qh NEWfacets)) {
facet->visitid= qh visit_id;
FOREACHneighbor_(facet) {
if (neighbor->visitid != qh visit_id) {
vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim,
SETindex_(facet->neighbors, neighbor), 0);
if (qh DOintersections)
qh_printhyperplaneintersection(fp, facet, neighbor, vertices, black);
if (qh PRINTridges) {
vertexA= SETfirstt_(vertices, vertexT);
vertexB= SETsecondt_(vertices, vertexT);
qh_printline3geom(fp, vertexA->point, vertexB->point, green);
}
qh_setfree(&vertices);
}
}
}
} /* printfacet3geom_simplicial */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet3math">-</a>
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, endfmt);
} /* printfacet3math */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet3vertex">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet4geom_nonsimplicial">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacet4geom_simplicial">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacetNvertex_nonsimplicial">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacetNvertex_simplicial">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacetheader">-</a>
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, -1);
+ 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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacetridges">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printfacets">-</a>
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, -1);
+ 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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhyperplaneintersection">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printline3geom">-</a>
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]);
}
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printneighborhood">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printpoint">-</a>
qh_printpoint( fp, string, point )
qh_printpointid( fp, string, dim, point, id )
prints the coordinates of a point
returns:
if string is defined
- prints 'string p%d' (skips p%d if id=-1)
+ prints 'string p%d'. Skips p%d if id=qh_IDunknown(-1)
notes:
nop if point is NULL
- prints id unless it is undefined (-1)
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 != -1)
+ if (id != qh_IDunknown)
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printpoint3">-</a>
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
*/
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printpoints_out">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printpointvect">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printpointvect2">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printridge">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printspheres">-</a>
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
*/
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvdiagram">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvdiagram2">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvertex">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvertexlist">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvertices">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvneighbors">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvoronoi">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvnorm">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printvridge">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="projectdim3">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="readfeasible">-</a>
qh_readfeasible( dim, curline )
read feasible point from current line and qh.fin
returns:
number of lines read from qh.fin
- sets qh.FEASIBLEpoint with malloc'd coordinates
+ 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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="readpoints">-</a>
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=
(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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="setfeasible">-</a>
qh_setfeasible( dim )
- set qh.FEASIBLEpoint from qh.feasible_string in "n,n,n" or "n n n" format
+ 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()
*/
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="skipfacet">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="skipfilename">-</a>
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/libqhull/libqhull.c b/src/libqhull/libqhull.c
index 44eda27..e637ff3 100644
--- a/src/libqhull/libqhull.c
+++ b/src/libqhull/libqhull.c
@@ -1,1401 +1,1401 @@
/*<html><pre> -<a href="qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/libqhull.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/libqhull.c#9 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_a.h"
/*============= functions in alphabetic order after qhull() =======*/
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="qhull">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="addpoint">-</a>
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) == -1)
+ 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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="build_withrestart">-</a>
qh_build_withrestart()
allow restarts due to qh.JOGGLEmax while calling qh_buildhull()
qh.FIRSTpoint/qh.NUMpoints is point array
it may be moved by qh_joggleinput()
*/
void qh_build_withrestart(void) {
int restart;
qh ALLOWrestart= True;
while (True) {
restart= setjmp(qh restartexit); /* simple statement for CRAY J916 */
if (restart) { /* only from qh_precision() */
zzinc_(Zretry);
wmax_(Wretrymax, qh JOGGLEmax);
/* QH7078 warns about using 'TCn' with 'QJn' */
- qh STOPcone= -1; /* if break from joggle, prevents normal output */
+ 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 != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
+ 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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="buildhull">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="buildtracing">-</a>
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 != -1 && qh TRACEdist < REALmax/2) {
+ }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) {
zinc_(Zvisit);
qh visit_id= 0;
FORALLfacets
facet->visitid= 0;
}
zmax_(Zvvisit2max, (int)qh vertex_visit/2);
- if (qh vertex_visit > (unsigned) INT_MAX/2) { /* 31 bits */
+ if (qh vertex_visit > (unsigned) INT_MAX) {
zinc_(Zvvisit);
qh vertex_visit= 0;
FORALLvertices
vertex->visitid= 0;
}
qh furthest_id= furthestid;
qh RANDOMdist= qh old_randomdist;
} /* buildtracing */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="errexit2">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="findhorizon">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="nextfurthest">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="partitionall">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="partitioncoplanar">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="partitionpoint">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="partitionvisible">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="precision">-</a>
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));
longjmp(qh restartexit, qh_ERRprec);
}
}
} /* qh_precision */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="printsummary">-</a>
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/libqhull/libqhull.h b/src/libqhull/libqhull.h
index aa6f91b..d1aa59e 100644
--- a/src/libqhull/libqhull.h
+++ b/src/libqhull/libqhull.h
@@ -1,1101 +1,1117 @@
/*<html><pre> -<a href="qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/libqhull.h#11 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/libqhull.h#16 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$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 ==============*/
#include "user.h" /* user definable constants (e.g., qh_QHpointer) */
#include <setjmp.h>
#include <float.h>
#include <time.h>
#include <stdio.h>
#if __MWERKS__ && __POWERPC__
#include <SIOUX.h>
#include <Files.h>
#include <Desk.h>
#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 */
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="coordT">-</a>
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
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="pointT">-</a>
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;
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="flagT">-</a>
flagT
Boolean flag as a bit
*/
#define flagT unsigned int
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="boolT">-</a>
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
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="CENTERtype">-</a>
qh_CENTER
to distinguish facet->center
*/
typedef enum
{
qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum
}
qh_CENTER;
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_PRINT">-</a>
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;
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_ALL">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_ERR">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_FILEstderr">-</a>
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
*/
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
#ifndef DEFqhstatT
#define DEFqhstatT 1
typedef struct qhstatT qhstatT; /* defined in stat.h */
#endif
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="facetT">-</a>
facetT
defines a facet
notes:
qhull() generates the hull as a list of facets.
topological information:
f.previous,next doubly-linked list of facets
f.vertices set of vertices
f.ridges set of ridges
f.neighbors set of neighbors
f.toporient True if facet has top-orientation (else bottom)
geometric information:
f.offset,normal hyperplane equation
f.maxoutside offset to outer plane -- all points inside
f.center centrum for testing convexity
f.simplicial True if facet is simplicial
f.flipped True if facet does not include qh.interior_point
for constructing hull:
f.visible True if facet on list of visible facets (will be deleted)
f.newfacet True if facet on list of newly created facets
f.coplanarset set of points coplanar with this facet
(includes near-inside points for later testing)
f.outsideset set of points outside of this facet
f.furthestdist distance to furthest point of outside set
f.visitid marks visited facets during a loop
f.replace replacement facet for to-be-deleted, visible facets
f.samecycle,newcycle cycle of facets for merging into horizon facet
see below for other flags and fields
*/
struct facetT {
#if !qh_COMPUTEfurthest
coordT furthestdist;/* distance to furthest point of outsideset */
#endif
#if qh_MAXoutside
coordT maxoutside; /* max computed distance of point to facet
Before QHULLfinished this is an approximation
since maxdist not always set for mergefacet
Actual outer plane is +DISTround and
computed outer plane is +2*DISTround */
#endif
coordT offset; /* exact offset of hyperplane from origin */
coordT *normal; /* normal of hyperplane, hull_dim coefficients */
/* if tricoplanar, shared with a neighbor */
union { /* in order of testing */
realT area; /* area of facet, only in io.c if ->isarea */
facetT *replace; /* replacement facet if ->visible and NEWfacets
is NULL only if qh_mergedegen_redundant or interior */
facetT *samecycle; /* cycle of facets from the same visible/horizon intersection,
if ->newfacet */
facetT *newcycle; /* in horizon facet, current samecycle of new facets */
facetT *trivisible; /* visible facet for ->tricoplanar facets during qh_triangulate() */
facetT *triowner; /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
}f;
coordT *center; /* centrum for convexity, qh.CENTERtype == qh_AScentrum */
/* Voronoi center, qh.CENTERtype == qh_ASvoronoi */
/* if tricoplanar, shared with a neighbor */
facetT *previous; /* previous facet in the facet_list */
facetT *next; /* next facet in the facet_list */
setT *vertices; /* vertices for this facet, inverse sorted by ID
if simplicial, 1st vertex was apex/furthest */
setT *ridges; /* explicit ridges for nonsimplicial facets.
for simplicial facets, neighbors 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 ->center, ->normal, ->offset, ->maxoutside */
/* all tricoplanars share the same apex */
/* if ->degenerate, does not span facet (one logical ridge) */
/* one tricoplanar has ->keepcentrum and ->coplanarset */
/* during qh_triangulate, f.trivisible points to original facet */
flagT newfacet:1; /* True if facet on qh.newfacet_list (new or merged) */
flagT visible:1; /* True if visible facet (will be deleted) */
flagT toporient:1; /* True if created with top orientation
after merging, use ridge orientation */
flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
flagT seen:1; /* used to perform operations only once, like visitid */
flagT seen2:1; /* used to perform operations only once, like visitid */
flagT flipped:1; /* True if facet is flipped */
flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
flagT notfurthest:1; /* True if last point of outsideset is not furthest*/
/*-------- flags primarily for output ---------*/
flagT good:1; /* True if a facet marked good for output */
flagT isarea:1; /* True if facet->f.area is defined */
/*-------- flags for merging ------------------*/
flagT dupridge:1; /* True if duplicate ridge in facet */
flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
->normal defined (also defined for mergeridge2) */
flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */
flagT coplanar:1; /* True if horizon facet is coplanar at last use */
flagT mergehorizon:1; /* True if will merge into horizon (->coplanar) */
flagT cycledone:1;/* True if mergecycle_all already done */
flagT tested:1; /* True if facet convexity has been tested (false after merge */
flagT keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
flagT newmerge:1; /* True if facet is newly merged for reducevertices */
flagT degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
flagT redundant:1; /* True if facet is redundant (degen_mergeset) */
};
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="ridgeT">-</a>
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:24; /* unique identifier, =>room for 8 flags, bit field matches qh.ridge_id */
+ unsigned id; /* unique identifier for 'f' output and debugging, ignored if overflow */
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 */
};
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="vertexT">-</a>
vertexT
defines a vertex
topological information:
next,previous doubly-linked list of all vertices
neighbors set of adjacent facets (only if qh.VERTEXneighbors)
geometric information:
point array of DIM3 coordinates
*/
struct vertexT {
vertexT *next; /* next vertex in vertex_list */
vertexT *previous; /* previous vertex in vertex_list */
pointT *point; /* hull_dim coordinates (coordT) */
setT *neighbors; /* neighboring facets of vertex, qh_vertexneighbors()
inits in io.c or after first merge */
- unsigned visitid:31; /* for use with qh.vertex_visit, size must match */
- flagT seen2:1; /* another seen flag */
- unsigned id:24; /* unique identifier, bit field matches qh.vertex_id */
- unsigned dim:4; /* dimension of point if non-zero, used by cpp */
- /* =>room for 4 flags */
+ unsigned id; /* unique identifier, size matches qh.vertex_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 */
};
-#define MAX_vdim 15 /* Maximum size of vertex->dim */
-
/*======= -global variables -qh ============================*/
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh">-</a>
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 multithreaded. Global state could be stored in thread-local storage.
*/
-extern int qhull_inuse;
-
typedef struct qhT qhT;
#if qh_QHpointer_dllimport
#define qh qh_qh->
__declspec(dllimport) extern qhT *qh_qh; /* allocated in global.c */
+#define QHULL_LIB_CHECK qh_lib_check(1, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(1, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
#elif qh_QHpointer
#define qh qh_qh->
extern qhT *qh_qh; /* allocated in global.c */
+#define QHULL_LIB_CHECK qh_lib_check(1, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(1, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
#elif qh_dllimport
#define qh qh_qh.
__declspec(dllimport) extern qhT qh_qh; /* allocated in global.c */
+#define QHULL_LIB_CHECK qh_lib_check(0, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(0, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
#else
#define qh qh_qh.
extern qhT qh_qh;
+#define QHULL_LIB_CHECK qh_lib_check(0, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(0, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
#endif
struct qhT {
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-const">-</a>
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 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 normals (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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-prec">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-codetern">-</a>
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() */
char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
jmp_buf restartexit; /* restart label for qh_errexit, defined by setjmp() */
char jmpXtra2[40]; /* extra bytes in case jmp_buf is defined wrong by compiler*/
FILE *fin; /* pointer to input file, init by qh_meminit */
FILE *fout; /* pointer to output file */
FILE *ferr; /* pointer to error file */
pointT *interior_point; /* center point of the initial simplex*/
int normal_size; /* size in bytes for facet normals and point coords*/
int center_size; /* size in bytes for Voronoi centers */
int TEMPsize; /* size for small, temporary sets (in quick mem) */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-lists">-</a>
qh facet and vertex lists
defines lists of facets, new facets, visible facets, vertices, and
new vertices. Includes counts, next ids, and trace ids.
see:
qh_resetlists()
*/
facetT *facet_list; /* first facet */
facetT *facet_tail; /* end of facet_list (dummy facet) */
facetT *facet_next; /* next facet for buildhull()
previous facets do not have outside sets
NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
facetT *newfacet_list; /* list of new facets to end of facet_list */
facetT *visible_list; /* list of visible facets preceeding newfacet_list,
facet->visible set */
int num_visible; /* current number of visible facets */
unsigned tracefacet_id; /* set at init, then can print whenever */
facetT *tracefacet; /* set in newfacet/mergefacet, undone in delfacet*/
unsigned tracevertex_id; /* set at buildtracing, can print whenever */
vertexT *tracevertex; /* set in newvertex, undone in delvertex*/
vertexT *vertex_list; /* list of all vertices, to vertex_tail */
vertexT *vertex_tail; /* end of vertex_list (dummy vertex) */
vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
all vertices have 'newlist' set */
int num_facets; /* number of facets in facet_list
includes visble faces (num_visible) */
int num_vertices; /* number of vertices in facet_list */
int num_outside; /* number of points in outsidesets (for tracing and RANDOMoutside)
includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
int num_good; /* number of good facets (after findgood_all) */
unsigned facet_id; /* ID of next, new facet from newfacet() */
- unsigned ridge_id:24; /* ID of next, new ridge from newridge() */
- unsigned vertex_id:24; /* ID of next, new vertex from newvertex() */
+ unsigned ridge_id; /* ID of next, new ridge from newridge() */
+ unsigned vertex_id; /* ID of next, new vertex from newvertex() */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-var">-</a>
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 */
+ 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:31; /* unique ID for searching vertices, reset with qh_buildtracing */
+ 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) */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-set">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-buf">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-static">-</a>
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- =========================*/
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="otherfacet_">-</a>
otherfacet_(ridge, facet)
return neighboring facet for a ridge in facet
*/
#define otherfacet_(ridge, facet) \
(((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="getid_">-</a>
getid_(p)
return int ID for facet, ridge, or vertex
- return -1 if NULL
+ return qh_IDunknown(-1) if NULL
*/
-#define getid_(p) ((p) ? (int)((p)->id) : -1)
+#define getid_(p) ((p) ? (int)((p)->id) : qh_IDunknown)
/*============== FORALL macros ===================*/
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLfacets">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLpoints">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLpoint_">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLvertices">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHfacet_">-</a>
FOREACHfacet_( facets ) { ... }
assign 'facet' to each facet in facets
declare:
facetT *facet, **facetp;
see:
<a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHneighbor_">-</a>
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:
<a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHneighbor_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighbor)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHpoint_">-</a>
FOREACHpoint_( points ) { ... }
assign 'point' to each point in points set
declare:
pointT *point, **pointp;
see:
<a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHpoint_(points) FOREACHsetelement_(pointT, points, point)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHridge_">-</a>
FOREACHridge_( ridges ) { ... }
assign 'ridge' to each ridge in ridges set
declare:
ridgeT *ridge, **ridgep;
see:
<a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHridge_(ridges) FOREACHsetelement_(ridgeT, ridges, ridge)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertex_">-</a>
FOREACHvertex_( vertices ) { ... }
assign 'vertex' to each vertex in vertices set
declare:
vertexT *vertex, **vertexp;
see:
<a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHfacet_i_">-</a>
FOREACHfacet_i_( facets ) { ... }
assign 'facet' and 'facet_i' for each facet in facets set
declare:
facetT *facet;
int facet_n, facet_i;
see:
<a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHfacet_i_(facets) FOREACHsetelement_i_(facetT, facets, facet)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHneighbor_i_">-</a>
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:
<a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHneighbor_i_(facet) FOREACHsetelement_i_(facetT, facet->neighbors, neighbor)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHpoint_i_">-</a>
FOREACHpoint_i_( points ) { ... }
assign 'point' and 'point_i' for each point in points set
declare:
pointT *point;
int point_n, point_i;
see:
<a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHpoint_i_(points) FOREACHsetelement_i_(pointT, points, point)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHridge_i_">-</a>
FOREACHridge_i_( ridges ) { ... }
assign 'ridge' and 'ridge_i' for each ridge in ridges set
declare:
ridgeT *ridge;
int ridge_n, ridge_i;
see:
<a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHridge_i_(ridges) FOREACHsetelement_i_(ridgeT, ridges, ridge)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertex_i_">-</a>
FOREACHvertex_i_( vertices ) { ... }
assign 'vertex' and 'vertex_i' for each vertex in vertices set
declare:
vertexT *vertex;
int vertex_n, vertex_i;
see:
<a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#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_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 isQHpointer, 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_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*/);
/********* -rboxpoints.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/libqhull/libqhull.pro b/src/libqhull/libqhull.pro
index 6541ee3..d804ed1 100644
--- a/src/libqhull/libqhull.pro
+++ b/src/libqhull/libqhull.pro
@@ -1,36 +1,67 @@
# -------------------------------------------------
# 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
-include(../qhull-libqhull-src.pri)
+# 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 += global.c
+SOURCES += stat.c
+SOURCES += geom2.c
+SOURCES += poly2.c
+SOURCES += merge.c
+SOURCES += libqhull.c
+SOURCES += geom.c
+SOURCES += poly.c
+SOURCES += qset.c
+SOURCES += mem.c
+SOURCES += random.c
+SOURCES += usermem.c
+SOURCES += userprintf.c
+SOURCES += io.c
+SOURCES += user.c
+SOURCES += rboxlib.c
+SOURCES += userprintf_rbox.c
+
+HEADERS += geom.h
+HEADERS += io.h
+HEADERS += libqhull.h
+HEADERS += mem.h
+HEADERS += merge.h
+HEADERS += poly.h
+HEADERS += random.h
+HEADERS += qhull_a.h
+HEADERS += qset.h
+HEADERS += stat.h
+HEADERS += 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/libqhull/mem.c b/src/libqhull/mem.c
index 5c724be..18fdc80 100644
--- a/src/libqhull/mem.c
+++ b/src/libqhull/mem.c
@@ -1,549 +1,578 @@
/*<html><pre> -<a href="qh-mem.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/mem.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/mem.c#8 $$Change: 1930 $
+ $DateTime: 2015/07/12 15:15:42 $$Author: bbarber $
*/
#include "mem.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#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_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 ======== */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="intcompare">-</a>
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 */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memalloc">-</a>
qh_memalloc( insize )
returns object of insize bytes
qhmem is the global memory structure
returns:
pointer to allocated memory
errors if insufficient memory
notes:
use explicit type conversion to avoid type warnings on some compilers
actual object may be larger than insize
use qh_memalloc_() for inline code for quick allocations
logs allocations if 'T5'
design:
if size < qhmem.LASTsize
if qhmem.freelists[size] non-empty
return first object on freelist
else
round up request to size of qhmem.freelists[size]
allocate new allocation buffer if necessary
allocate object from allocation buffer
else
allocate object with 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 */
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 */
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="memfree">-</a>
+
+ qh_memcheck( )
+*/
+void qh_memcheck() {
+ 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: 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 */
+
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memfree">-</a>
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;
qh_free(object);
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);
}
} /* memfree */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memfreeshort">-</a>
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 */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="meminit">-</a>
qh_meminit( ferr )
initialize qhmem and test sizeof( void*)
*/
void qh_meminit(FILE *ferr) {
memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
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() */
}
} /* meminit */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="meminitbuffers">-</a>
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 */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memsetup">-</a>
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 */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memsize">-</a>
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 */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memstatistics">-</a>
qh_memstatistics( fp )
print out memory statistics
Verifies that qhmem.totfree == sum of freelists
*/
void qh_memstatistics(FILE *fp) {
int i, count, totfree= 0;
void *object;
for (i=0; i < qhmem.TABLEsize; i++) {
count=0;
for (object= qhmem.freelists[i]; object; object= *((void **)object))
count++;
totfree += qhmem.sizetable[i] * count;
}
if (totfree != qhmem.totfree) {
qh_fprintf(qhmem.ferr, 6211, "qh_memstatistics internal error: totfree %d not equal to freelist total %d\n", qhmem.totfree, totfree);
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
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 */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
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 */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memtotlong">-</a>
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/libqhull/mem.h b/src/libqhull/mem.h
index b7f4a4d..273cff8 100644
--- a/src/libqhull/mem.h
+++ b/src/libqhull/mem.h
@@ -1,219 +1,221 @@
/*<html><pre> -<a href="qh-mem.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/mem.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/mem.h#9 $$Change: 1880 $
+ $DateTime: 2015/04/19 21:29:35 $$Author: bbarber $
*/
#ifndef qhDEFmem
#define qhDEFmem 1
#include <stdio.h>
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
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
*/
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="TRACEshort">-</a>
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 <a href="user.h#MEMalign">qh_MEMalign</a> 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 */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="ptr_intT">-</a>
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.
+ This matches Qt convention and is easier to work with.
*/
-#if _MSC_VER && defined(_WIN64)
+#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
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="qhmemT">-</a>
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 ====================*/
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memalloc_">-</a>
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
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memfree_">-</a>
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_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/libqhull/merge.c b/src/libqhull/merge.c
index 6a4e542..237f6f3 100644
--- a/src/libqhull/merge.c
+++ b/src/libqhull/merge.c
@@ -1,3623 +1,3623 @@
/*<html><pre> -<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/merge.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/merge.c#8 $$Change: 1831 $
+ $DateTime: 2015/02/07 20:31:47 $$Author: bbarber $
*/
#include "qhull_a.h"
#ifndef qh_NOmerge
/*===== functions(alphabetical after premerge and postmerge) ======*/
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="premerge">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="postmerge">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="all_merges">-</a>
qh_all_merges( othermerge, vneighbors )
merge all non-convex facets
set othermerge if already merged facets (for qh_reducevertices)
if vneighbors
tests vertex neighbors for convexity at end
qh.facet_mergeset lists the non-convex ridges in qh_newfacet_list
qh.degen_mergeset is defined
if qh.MERGEexact && !qh.POSTmerging,
does not merge coplanar facets
returns:
deleted facets added to qh.visible_list with facet->visible
deleted vertices added qh.delvertex_list with vertex->delvertex
notes:
unless !qh.MERGEindependent,
merges facets in independent sets
uses qh.newfacet_list as argument since merges call qh_removefacet()
design:
while merges occur
for each merge in qh.facet_mergeset
unless one of the facets was already merged in this pass
merge the facets
test merged facets for additional merges
add merges to qh.facet_mergeset
if vertices record neighboring facets
rename redundant vertices
update qh.facet_mergeset
if vneighbors ??
tests vertex neighbors for convexity at end
*/
void qh_all_merges(boolT othermerge, boolT vneighbors) {
facetT *facet1, *facet2;
mergeT *merge;
boolT wasmerge= True, isreduce;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="appendmergeset">-</a>
qh_appendmergeset( facet, neighbor, mergetype, angle )
appends an entry to qh.facet_mergeset or qh.degen_mergeset
angle ignored if NULL or !qh.ANGLEmerge
returns:
merge appended to facet_mergeset or degen_mergeset
sets ->degenerate or ->redundant if degen_mergeset
see:
qh_test_appendmerge()
design:
allocate merge entry
if regular merge
append to qh.facet_mergeset
else if degenerate merge and qh.facet_mergeset is all degenerate
append to qh.degen_mergeset
else if degenerate merge
prepend to qh.degen_mergeset
else if redundant merge
append to qh.degen_mergeset
*/
void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle) {
mergeT *merge, *lastmerge;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="basevertices">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="checkconnect">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="checkzero">-</a>
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) {
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="compareangle">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="comparemerge">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="comparevisit">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="copynonconvex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="degen_redundant_facet">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="degen_redundant_neighbors">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="find_newvertex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="findbest_test">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="findbestneighbor">-</a>
qh_findbestneighbor( facet, dist, mindist, maxdist )
finds best neighbor (least dist) of a facet for merging
returns:
returns min and max distances and their max absolute value
notes:
avoids merging old into new
assumes ridge->nonconvex only set on one ridge between a pair of facets
could use an early out predicate but not worth it
design:
if a large facet
will test centrum
else
will test vertices
if a large facet
test nonconvex neighbors for best merge
else
test all neighbors for the best merge
if testing centrum
get distance information
*/
facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp) {
facetT *neighbor, **neighborp, *bestfacet= NULL;
ridgeT *ridge, **ridgep;
boolT nonconvex= True, testcentrum= False;
int size= qh_setsize(facet->vertices);
*distp= REALmax;
if (size > qh_BESTcentrum2 * qh hull_dim + qh_BESTcentrum) {
testcentrum= True;
zinc_(Zbestcentrum);
if (!facet->center)
facet->center= qh_getcentrum(facet);
}
if (size > qh hull_dim + qh_BESTnonconvex) {
FOREACHridge_(facet->ridges) {
if (ridge->nonconvex) {
neighbor= otherfacet_(ridge, facet);
qh_findbest_test(testcentrum, facet, neighbor,
&bestfacet, distp, mindistp, maxdistp);
}
}
}
if (!bestfacet) {
nonconvex= False;
FOREACHneighbor_(facet)
qh_findbest_test(testcentrum, facet, neighbor,
&bestfacet, distp, mindistp, maxdistp);
}
if (!bestfacet) {
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="flippedmerges">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="forcedmerges">-</a>
qh_forcedmerges( wasmerge )
merge duplicated ridges
returns:
removes all duplicate ridges on facet_mergeset
wasmerge set if merge
qh.facet_mergeset may include non-forced merges(none for now)
qh.degen_mergeset includes degen/redun merges
notes:
duplicate ridges occur when the horizon is pinched,
i.e. a subridge occurs in more than two horizon ridges.
could rename vertices that pinch the horizon
assumes qh_merge_degenredundant() has not be called
othermerges isn't needed since facet_mergeset is empty afterwards
keep it in case of change
design:
for each duplicate ridge
find current facets by chasing f.replace links
determine best direction for facet
merge one facet into the other
remove duplicate ridges from qh.facet_mergeset
*/
void qh_forcedmerges(boolT *wasmerge) {
facetT *facet1, *facet2;
mergeT *merge, **mergep;
realT dist1, dist2, mindist1, mindist2, maxdist1, maxdist2;
setT *othermerges;
int nummerge=0, numflip=0;
if (qh TRACEmerge-1 == zzval_(Ztotmerge))
qhmem.IStracing= qh IStracing= qh TRACElevel;
trace4((qh ferr, 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;
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);
}
if (qh TRACEmerge-1 == zzval_(Ztotmerge))
qhmem.IStracing= qh IStracing= qh TRACElevel;
dist1= qh_getdistance(facet1, facet2, &mindist1, &maxdist1);
dist2= qh_getdistance(facet2, facet1, &mindist2, &maxdist2);
trace0((qh ferr, 16, "qh_forcedmerges: duplicate ridge between f%d and f%d, dist %2.2g and reverse dist %2.2g during p%d\n",
facet1->id, facet2->id, dist1, dist2, qh furthest_id));
if (dist1 < dist2)
qh_mergefacet(facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex);
else {
qh_mergefacet(facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex);
dist1= dist2;
facet1= facet2;
}
if (facet1->flipped) {
zinc_(Zmergeflipdup);
numflip++;
}else
nummerge++;
if (qh PRINTstatistics) {
zinc_(Zduplicate);
wadd_(Wduplicatetot, dist1);
wmax_(Wduplicatemax, dist1);
}
}
FOREACHmerge_(othermerges) {
if (merge->type == MRGridge)
qh_memfree(merge, (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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="getmergeset">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="getmergeset_initial">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="hashridge">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="hashridge_find">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="makeridges">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mark_dupridges">-</a>
qh_mark_dupridges( facetlist )
add duplicated ridges to qh.facet_mergeset
facet->dupridge is true
returns:
duplicate ridges on qh.facet_mergeset
->mergeridge/->mergeridge2 set
duplicate ridges marked by qh_MERGEridge and both sides facet->dupridge
no MERGEridges in neighbor sets
notes:
duplicate ridges occur when the horizon is pinched,
i.e. a subridge occurs in more than two horizon ridges.
could rename vertices that pinch the horizon
uses qh.visit_id
design:
for all facets on facetlist
if facet contains a duplicate ridge
for each neighbor of facet
if neighbor marked qh_MERGEridge (one side of the merge)
set facet->mergeridge
else
if neighbor contains a duplicate ridge
and the back link is qh_MERGEridge
append duplicate ridge to qh.facet_mergeset
for each duplicate ridge
make ridge sets in preparation for merging
remove qh_MERGEridge from neighbor set
for each duplicate ridge
restore the missing neighbor from the neighbor set that was qh_MERGEridge
add the missing ridge for this neighbor
*/
void qh_mark_dupridges(facetT *facetlist) {
facetT *facet, *neighbor, **neighborp;
int nummerge=0;
mergeT *merge, **mergep;
trace4((qh ferr, 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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="maydropneighbor">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="merge_degenredundant">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="merge_nonconvex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergecycle">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergecycle_all">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergecycle_facets">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergecycle_neighbors">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergecycle_ridges">-</a>
qh_mergecycle_ridges( samecycle, newfacet )
add ridges/neighbors for facets in samecycle to newfacet
all new/old neighbors of newfacet marked with qh.visit_id
facets in samecycle marked with qh.visit_id-1
newfacet marked with qh.visit_id
returns:
newfacet has merged ridges
notes:
ridge already updated for simplicial neighbors of samecycle with a ridge
see:
qh_mergeridges()
qh_makeridges()
design:
remove ridges between newfacet and samecycle
for each facet in samecycle
for each ridge in facet
update facet pointers in ridge
skip ridges processed in qh_mergecycle_neighors
free ridges between newfacet and samecycle
free ridges between facets of samecycle (on 2nd visit)
append remaining ridges to newfacet
if simpilicial facet
for each neighbor of facet
if simplicial facet
and not samecycle facet or newfacet
make ridge between neighbor and newfacet
*/
void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) {
facetT *same, *neighbor= NULL;
int numold=0, numnew=0;
int neighbor_i, neighbor_n;
unsigned int samevisitid;
ridgeT *ridge, **ridgep;
boolT toporient;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergecycle_vneighbors">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergefacet">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergefacet2d">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergeneighbors">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergeridges">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergesimplex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergevertex_del">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergevertex_neighbors">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="mergevertices">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="neighbor_intersections">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="newvertices">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="reducevertices">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="redundant_vertex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="remove_extravertices">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="rename_sharedvertex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="renameridgevertex">-</a>
qh_renameridgevertex( ridge, oldvertex, newvertex )
renames oldvertex as newvertex in ridge
returns:
design:
delete oldvertex from ridge
if newvertex already in ridge
copy ridge->noconvex to another ridge if possible
delete the ridge
else
insert newvertex into the ridge
adjust the ridge's orientation
*/
void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) {
int nth= 0, oldnth;
facetT *temp;
vertexT *vertex, **vertexp;
oldnth= qh_setindex(ridge->vertices, oldvertex);
qh_setdelnthsorted(ridge->vertices, oldnth);
FOREACHvertex_(ridge->vertices) {
if (vertex == newvertex) {
zinc_(Zdelridge);
if (ridge->nonconvex) /* only one ridge has nonconvex set */
qh_copynonconvex(ridge);
qh_delridge(ridge);
trace2((qh ferr, 2038, "qh_renameridgevertex: ridge r%d deleted. It contained both v%d and v%d\n",
ridge->id, oldvertex->id, newvertex->id));
return;
}
if (vertex->id < newvertex->id)
break;
nth++;
}
qh_setaddnth(&ridge->vertices, nth, newvertex);
if (abs(oldnth - nth)%2) {
trace3((qh ferr, 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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="renamevertex">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="test_appendmerge">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="test_vneighbors">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="tracemerge">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="tracemerging">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="updatetested">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="vertexridges">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="vertexridges_facet">-</a>
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 */
/*-<a href="qh-merge.htm#TOC"
>-------------------------------</a><a name="willdelete">-</a>
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/libqhull/poly.c b/src/libqhull/poly.c
index cfb0e7b..9e3dba5 100644
--- a/src/libqhull/poly.c
+++ b/src/libqhull/poly.c
@@ -1,1199 +1,1199 @@
/*<html><pre> -<a href="qh-poly.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/poly.c#8 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/poly.c#12 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_a.h"
/*======== functions in alphabetical order ==========*/
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="appendfacet">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="appendvertex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="attachnewfacets">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="checkflipped">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="delfacet">-</a>
qh_delfacet( facet )
removes facet from facet_list and frees up its memory
notes:
assumes vertices and ridges already freed
*/
void qh_delfacet(facetT *facet) {
- void **freelistp; /* used !qh_NOmem */
+ 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) { /* uses macro calls */
qh_memfree_(facet->center, qh center_size, freelistp);
}else /* AScentrum */ {
qh_memfree_(facet->center, qh normal_size, freelistp);
}
}
qh_setfree(&(facet->neighbors));
if (facet->ridges)
qh_setfree(&(facet->ridges));
qh_setfree(&(facet->vertices));
if (facet->outsideset)
qh_setfree(&(facet->outsideset));
if (facet->coplanarset)
qh_setfree(&(facet->coplanarset));
qh_memfree_(facet, (int)sizeof(facetT), freelistp);
} /* delfacet */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="deletevisible">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="facetintersect">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="gethash">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="makenewfacet">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="makenewplanes">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="makenew_nonsimplicial">-</a>
qh_makenew_nonsimplicial( visible, apex, numnew )
make new facets for ridges of a visible facet
returns:
first newfacet, bumps numnew as needed
attaches new facets if !qh.ONLYgood
marks ridge neighbors for simplicial visible
if (qh.ONLYgood)
ridges on newfacet, horizon, and visible
else
ridge and neighbors between newfacet and horizon
visible facet's ridges are deleted
notes:
qh.visit_id if visible has already been processed
sets neighbor->seen for building f.samecycle
assumes all 'seen' flags initially false
design:
for each ridge of visible facet
get neighbor of visible facet
if neighbor was already processed
delete the ridge (will delete all visible facets later)
if neighbor is a horizon facet
create a new facet
if neighbor coplanar
adds newfacet to f.samecycle for later merging
else
updates neighbor's neighbor set
(checks for non-simplicial facet with multiple ridges to visible facet)
updates neighbor's ridge set
(checks for simplicial neighbor to non-simplicial visible facet)
(deletes ridge if neighbor is simplicial)
*/
#ifndef qh_NOmerge
facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew) {
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="makenew_simplicial">-</a>
qh_makenew_simplicial( visible, apex, numnew )
make new facets for simplicial visible facet and apex
returns:
attaches new facets if (!qh.ONLYgood)
neighbors between newfacet and horizon
notes:
nop if neighbor->seen or neighbor->visible(see qh_makenew_nonsimplicial)
design:
locate neighboring horizon facet for visible facet
determine vertices and orientation
create new facet
if coplanar,
add new facet to f.samecycle
update horizon facet's neighbor list
*/
facetT *qh_makenew_simplicial(facetT *visible, vertexT *apex, int *numnew) {
facetT *neighbor, **neighborp, *newfacet= NULL;
setT *vertices;
boolT flip, toporient;
- int horizonskip, visibleskip;
+ 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="matchneighbor">-</a>
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);
SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge;
matchfacet->dupridge= True;
if (!matchfacet->normal)
qh_setfacetplane(matchfacet);
qh_addhash(matchfacet, qh hash_table, hashsize, hash);
*hashcount += 2;
}
}
trace4((qh ferr, 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="matchnewfacets">-</a>
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; newskip<qh hull_dim; newskip++) /* furthest/horizon already matched */
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="matchvertices">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="newfacet">-</a>
qh_newfacet()
return a new facet
returns:
all fields initialized or cleared (NULL)
preallocates neighbors set
*/
facetT *qh_newfacet(void) {
facetT *facet;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="newridge">-</a>
qh_newridge()
return a new ridge
*/
ridgeT *qh_newridge(void) {
ridgeT *ridge;
- void **freelistp; /* used !qh_NOmem */
+ 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 == 0xFFFFFF) {
+ if (qh ridge_id == 0xFFFFFFFF) {
qh_fprintf(qh ferr, 7074, "\
-qhull warning: more than %d ridges. ID field overflows and two ridges\n\
-may have the same identifier. Otherwise output ok.\n", 0xFFFFFF);
+qhull warning: more than 2^32 ridges. Qhull results are OK. 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="pointid">-</a>
qh_pointid( )
return id for a point,
- returns -3 if null, -2 if interior, or -1 if not known
+ returns qh_IDnone(-3) if null, qh_IDinterior(-2) if interior, or qh_IDunknown(-1) if not known
alternative code:
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 -3;
+ return qh_IDnone;
else if (point == qh interior_point)
- return -2;
+ 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 -1;
+ return qh_IDunknown;
return (int)id;
} /* pointid */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="removefacet">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="removevertex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="updatevertices">-</a>
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/libqhull/poly2.c b/src/libqhull/poly2.c
index 4c0da1b..41a9330 100644
--- a/src/libqhull/poly2.c
+++ b/src/libqhull/poly2.c
@@ -1,3154 +1,3152 @@
/*<html><pre> -<a href="qh-poly.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/poly2.c#8 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/poly2.c#11 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_a.h"
/*======== functions in alphabetical order ==========*/
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="addhash">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="check_bestdist">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="check_maxout">-</a>
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->id);
}
}
}while
(maxoutside > 2*old_maxoutside);
/* if qh.maxoutside increases substantially, qh_SEARCHdist is not valid
e.g., RBOX 5000 s Z1 G1e-13 t1001200614 | qhull */
zzadd_(Zcheckpart, numpart);
qh_settempfree(&facets);
wval_(Wmaxout)= maxoutside - qh max_outside;
wmax_(Wmaxoutside, qh max_outside);
qh max_outside= maxoutside;
qh_nearcoplanar(/*qh.facet_list*/);
qh maxoutdone= True;
trace1((qh ferr, 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
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="check_output">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="check_point">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="check_points">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="checkconvex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="checkfacet">-</a>
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 (!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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="checkflipped_all">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="checkpolygon">-</a>
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) == -1) {
+ 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="checkvertex">-</a>
qh_checkvertex( vertex )
check vertex for consistency
checks vertex->neighbors
notes:
neighbors checked efficiently in checkpolygon
*/
void qh_checkvertex(vertexT *vertex) {
boolT waserror= False;
facetT *neighbor, **neighborp, *errfacet=NULL;
- if (qh_pointid(vertex->point) == -1) {
+ 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="clearcenters">-</a>
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;
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="createsimplex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="delridge">-</a>
qh_delridge( ridge )
deletes ridge from data structures it belongs to
frees up its memory
notes:
in merge.c, caller sets vertex->delridge for each vertex
ridges also freed in qh_freeqhull
*/
void qh_delridge(ridgeT *ridge) {
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="delvertex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="facet3vertex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="findbestfacet">-</a>
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 <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
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:
<a href="geom.c#findbest">qh_findbest</a>
*/
facetT *qh_findbestfacet(pointT *point, boolT bestoutside,
realT *bestdist, boolT *isoutside) {
facetT *bestfacet= NULL;
int numpart, totpart= 0;
bestfacet= qh_findbest(point, qh facet_list,
bestoutside, !qh_ISnewfacets, bestoutside /* qh_NOupper */,
bestdist, isoutside, &totpart);
if (*bestdist < -qh DISTround) {
bestfacet= qh_findfacet_all(point, bestdist, isoutside, &numpart);
totpart += numpart;
if ((isoutside && bestoutside)
|| (!isoutside && bestfacet->upperdelaunay)) {
bestfacet= qh_findbest(point, bestfacet,
bestoutside, False, bestoutside,
bestdist, isoutside, &totpart);
totpart += numpart;
}
}
trace3((qh ferr, 3014, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
bestfacet->id, *bestdist, *isoutside, totpart));
return bestfacet;
} /* findbestfacet */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="findbestlower">-</a>
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;
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) {
qh_fprintf(qh ferr, 6228, "\n\
Qhull internal error (qh_findbestlower): all neighbors of facet %d are flipped or upper Delaunay.\n\
Please report this error to qhull_bug@qhull.org with the input and all of the output.\n",
upperfacet->id);
qh_errexit(qh_ERRqhull, upperfacet, NULL);
}
*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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="findfacet_all">-</a>
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:
for library users, not 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="findgood">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="findgood_all">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="furthestnext">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="furthestout">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="infiniteloop">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="initbuild">-</a>
qh_initbuild()
initialize hull and outside sets with point array
qh.FIRSTpoint/qh.NUMpoints is point array
if qh.GOODpoint
adds qh.GOODpoint to initial hull
returns:
qh_facetlist with initial hull
points partioned into outside sets, coplanar sets, or inside
initializes qh.GOODpointp, qh.GOODvertexp,
design:
initialize global variables used during qh_buildhull
determine precision constants and points with max/min coordinate values
if qh.SCALElast, scale last coordinate(for 'd')
build initial simplex
partition input points into facets of initial simplex
set up lists
if qh.ONLYgood
check consistency
add qh.GOODvertex if defined
*/
void qh_initbuild( void) {
setT *maxpoints, *vertices;
facetT *facet;
int i, numpart;
realT dist;
boolT isoutside;
- qh furthest_id= -1;
+ qh 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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="initialhull">-</a>
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 input error: Can not compute the upper Delaunay triangulation or upper Voronoi diagram of cocircular/cospherical points.\n");
else
qh_fprintf(qh ferr, 6239, "Qhull input error: Use option 'Qz' for the Delaunay triangulation or Voronoi diagram of cocircular/cospherical points. Option 'Qz' adds a point \"at infinity\" (above the corresponding paraboloid).\n");
qh_errexit(qh_ERRinput, NULL, NULL);
}
qh_precision("initial facet is coplanar with interior point");
qh_fprintf(qh ferr, 6154, "qhull precision error: initial facet %d is coplanar with the interior point\n",
facet->id);
qh_errexit(qh_ERRsingular, facet, NULL);
}
FOREACHneighbor_(facet) {
angle= qh_getangle(facet->normal, neighbor->normal);
minimize_( minangle, angle);
}
}
if (minangle < qh_MAXnarrow && !qh NOnarrow) {
realT diff= 1.0 + minangle;
qh NARROWhull= True;
qh_option("_narrow-hull", NULL, &diff);
if (minangle < qh_WARNnarrow && !qh RERUN && qh PRINTprecision)
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="initialvertices">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="isvertex">-</a>
qh_isvertex( )
returns vertex if point is in vertex set, else returns NULL
notes:
for qh.GOODvertex
*/
vertexT *qh_isvertex(pointT *point, setT *vertices) {
vertexT *vertex, **vertexp;
FOREACHvertex_(vertices) {
if (vertex->point == point)
return vertex;
}
return NULL;
} /* isvertex */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="makenewfacets">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="matchduplicates">-</a>
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;
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="nearcoplanar">-</a>
qh_nearcoplanar()
for all facets, remove near-inside points from facet->coplanarset</li>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="nearvertex">-</a>
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);
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)));
return bestvertex;
} /* nearvertex */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="newhashtable">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="newvertex">-</a>
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 == 0xFFFFFF) {
- qh_fprintf(qh ferr, 6159, "qhull error: more than %d vertices. ID field overflows and two vertices\n\
-may have the same identifier. Vertices will not be sorted correctly.\n", 0xFFFFFF);
+ if (qh vertex_id == 0xFFFFFFFF) {
+ 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;
- vertex->dim= (unsigned char)(qh hull_dim <= MAX_vdim ? qh hull_dim : 0);
trace4((qh ferr, 4060, "qh_newvertex: vertex p%d(v%d) created\n", qh_pointid(vertex->point),
vertex->id));
return(vertex);
} /* newvertex */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="nextridge3d">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="outcoplanar">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="point">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="point_add">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="pointfacet">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="pointvertex">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="prependfacet">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="printhashtable">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="printlists">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="resetlists">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="setvoronoi_all">-</a>
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
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="triangulate">-</a>
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) {
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 */
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="triangulate_facet">-</a>
qh_triangulate_facet(facetA)
triangulate a non-simplicial facet
if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center
returns:
qh.newfacet_list == simplicial facets
facet->tricoplanar set and ->keepcentrum false
facet->degenerate set if duplicated apex
facet->f.trivisible set to facetA
facet->center copied from facetA (created if qh_ASvoronoi)
qh_eachvoronoi, qh_detvridge, qh_detvridge3 assume centers copied
facet->normal,offset,maxoutside copied from facetA
notes:
qh_makenew_nonsimplicial uses neighbor->seen for the same
see also:
qh_addpoint() -- add a point
qh_makenewfacets() -- construct a cone of facets for a new vertex
design:
if qh_ASvoronoi,
compute Voronoi center (facet->center)
select first vertex (highest ID to preserve ID ordering of ->vertices)
triangulate from vertex to ridges
copy facet->center, normal, offset
update vertex neighbors
*/
void qh_triangulate_facet(facetT *facetA, vertexT **first_vertex) {
facetT *newfacet;
facetT *neighbor, **neighborp;
vertexT *apex;
int numnew=0;
trace3((qh ferr, 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) {
newfacet->keepcentrum= True;
newfacet->normal= qh_copypoints(facetA->normal, 1, qh hull_dim);
if (qh CENTERtype == qh_AScentrum)
newfacet->center= qh_getcentrum(newfacet);
else
newfacet->center= qh_copypoints(facetA->center, 1, qh hull_dim);
}else {
newfacet->keepcentrum= False;
newfacet->normal= facetA->normal;
newfacet->center= facetA->center;
}
newfacet->offset= facetA->offset;
#if qh_MAXoutside
newfacet->maxoutside= facetA->maxoutside;
#endif
}
qh_matchnewfacets(/*qh.newfacet_list*/);
zinc_(Ztricoplanar);
zadd_(Ztricoplanartot, numnew);
zmax_(Ztricoplanarmax, numnew);
qh visible_list= NULL;
if (!(*first_vertex))
(*first_vertex)= qh newvertex_list;
qh newvertex_list= NULL;
qh_updatevertices(/*qh.newfacet_list, empty visible_list and newvertex_list*/);
qh_resetlists(False, !qh_RESETvisible /*qh.newfacet_list, empty visible_list and newvertex_list*/);
} /* triangulate_facet */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="triangulate_link">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="triangulate_mirror">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="triangulate_null">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="vertexintersect">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="vertexintersect_new">-</a>
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 */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="vertexneighbors">-</a>
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: determing neighboring facets for each vertex\n"));
qh vertex_visit++;
FORALLfacets {
if (facet->visible)
continue;
FOREACHvertex_(facet->vertices) {
if (vertex->visitid != qh vertex_visit) {
vertex->visitid= qh vertex_visit;
vertex->neighbors= qh_setnew(qh hull_dim);
}
qh_setappend(&vertex->neighbors, facet);
}
}
qh VERTEXneighbors= True;
} /* vertexneighbors */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="vertexsubset">-</a>
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/libqhull/qh-globa.htm b/src/libqhull/qh-globa.htm
index 51a4611..5d0ae17 100644
--- a/src/libqhull/qh-globa.htm
+++ b/src/libqhull/qh-globa.htm
@@ -1,161 +1,162 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>global.c -- global variables and their functions</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<!-- Main text of document. -->
<h2>global.c -- global variables and their functions</h2>
<blockquote>
<p>Qhull uses a global data structure, <tt>qh</tt>, 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
<a href="user.h#QHpointer">QHpointer</a>.
</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <b>Global</b> &#149;
<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
<h3>Index to <a href="global.c">global.c</a> and
<a href="libqhull.h">libqhull.h</a></h3>
<ul>
<li><a href="#ovar">Qhull's global variables</a> </li>
<li><a href="#ofunc">Global variable and initialization
routines</a> </li>
</ul>
<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ovar">Qhull's global
variables</a></h3>
<ul>
<li><a href=global.c#qh_version>qh_version</a> version string
<li><a href="libqhull.h#qh">qh</a> all global variables for
qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
<li><a href="libqhull.h#qh-const">qh constants</a> configuration
flags and constants for Qhull </li>
<li><a href="libqhull.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
<li><a href="libqhull.h#qh-codetern">qh internal constants</a>
internal constants for Qhull </li>
<li><a href="libqhull.h#qh-lists">qh facet and vertex lists</a>
lists of facets and vertices </li>
<li><a href="libqhull.h#qh-var">qh global variables</a> minimum
and maximum distances, next visit ids, several flags, and
other global variables. </li>
<li><a href="libqhull.h#qh-set">qh global sets</a> global sets
for merging, hashing, input, etc. </li>
<li><a href="libqhull.h#qh-buf">qh global buffers</a> buffers
for matrix operations and input </li>
<li><a href="libqhull.h#qh-static">qh static variables</a>
static variables for individual functions </li>
</ul>
<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ofunc">Global variable and
initialization routines</a></h3>
<ul>
<li><a href="global.c#appendprint">qh_appendprint</a> append
output format to <tt>qh.PRINTout</tt> </li>
<li><a href="global.c#freebuffers">qh_freebuffers</a> free
global memory buffers </li>
<li><a href="global.c#freeqhull">qh_freeqhull</a> free memory
used by qhull </li>
<li><a href="global.c#init_A">qh_init_A</a> called before
error handling initialized </li>
<li><a href="global.c#init_B">qh_init_B</a> called after
points are defined </li>
<li><a href="global.c#init_qhull_command">qh_init_qhull_command</a>
build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
<li><a href="global.c#initflags">qh_initflags</a> set flags
and constants from command line </li>
<li><a href="global.c#initqhull_buffers">qh_initqhull_buffers</a>
initialize global memory buffers </li>
<li><a href="global.c#initqhull_globals">qh_initqhull_globals</a>
initialize global variables </li>
<li><a href="global.c#initqhull_mem">qh_initqhull_mem</a>
initialize Qhull memory management </li>
<li><a href="global.c#initqhull_start">qh_initqhull_start</a>
allocate qh_qh and call qh_initqhull_start2()
<li><a href="global.c#initqhull_start2">qh_initqhull_start2</a>
initialize default values at Qhull startup </li>
<li><a href="global.c#initthresholds">qh_initthresholds</a>
initialize 'Pdn' and 'PDn' thresholds </li>
+<li><a href="global.c#lib_check">qh_lib_check</a> check for compatible Qhull library</li>
<li><a href="global.c#option">qh_option</a> append option
description to <tt>qh.global_options</tt> </li>
<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
restores a previously saved qhull </li>
<li><a href="global.c#save_qhull">qh_save_qhull</a> saves
qhull for a later qh_restore_qhull() </li>
<li><a href="global.c#strtol">qh_strtol</a> duplicates
strtod() and strtol() </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhull/qh-mem.htm b/src/libqhull/qh-mem.htm
index 5aca0e1..22f8288 100644
--- a/src/libqhull/qh-mem.htm
+++ b/src/libqhull/qh-mem.htm
@@ -1,141 +1,143 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>mem.c -- memory operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>mem.c -- memory operations</h2>
<blockquote>
<p>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. </p>
<p>Use 'T5' to trace memory allocations.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
<a href="qh-io.htm#TOC">Io</a> &#149; <b>Mem</b>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="mem.c">mem.c</a> and
<a href="mem.h">mem.h</a></h3>
<ul>
<li><a href="#etype">mem.h data types</a> </li>
<li><a href="#emacro">mem.h macros</a> </li>
<li><a href="#efunc">User level functions</a> </li>
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="etype">mem.h data types and constants</a></h3>
<ul>
<li><a href="mem.h#ptr_intT">ptr_intT</a> for casting
a void* to an integer-type </li>
<li><a href="mem.h#qhmemT">qhmemT</a> global memory
structure for mem.c </li>
<li><a href="mem.h#NOmem">qh_NOmem</a> disable memory allocation</li>
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="emacro">mem.h macros</a></h3>
<ul>
<li><a href="mem.h#memalloc_">qh_memalloc_</a>
allocate memory</li>
<li><a href="mem.h#memfree_">qh_memfree_</a> free
memory</li>
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="efunc">User level
functions</a></h3>
<ul>
<li><a href="mem.c#memalloc">qh_memalloc</a> allocate
memory </li>
+<li><a href="mem.c#memcheck">qh_memcheck</a>
+quick check of memory for internal consistency</li>
<li><a href="mem.c#memfree">qh_memfree</a> free
memory </li>
<li><a href="mem.c#meminit">qh_meminit</a> initialize
memory </li>
<li><a href="mem.c#memstatistics">qh_memstatistics</a>
print memory statistics </li>
<li><a href="mem.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
<li><a href="mem.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="m">Initialization and
termination functions</a></h3>
<ul>
<li><a href="mem.c#intcompare">qh_intcompare</a> used by
qsort and bsearch to compare two integers </li>
<li><a href="mem.c#memfreeshort">qh_memfreeshort</a>
frees up all short and qhmem memory allocations </li>
<li><a href="mem.c#meminit">qh_meminit</a> initialize
memory </li>
<li><a href="mem.c#meminitbuffers">qh_meminitbuffers</a>
initialize qhmem </li>
<li><a href="mem.c#memsetup">qh_memsetup</a> set up
memory after running memsize() </li>
<li><a href="mem.c#memsize">qh_memsize</a> define a free
list for this size </li>
<li><a href="mem.c#memstatistics">qh_memstatistics</a>
print out memory statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhull/qhull-exports.def b/src/libqhull/qhull-exports.def
index 16e4a37..c3e7ba7 100644
--- a/src/libqhull/qhull-exports.def
+++ b/src/libqhull/qhull-exports.def
@@ -1,414 +1,414 @@
; 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 qhull_inuse rbox rbox_inuse
+; 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/2011/qhull/src/libqhull/qhull-exports.def#6 $$Change: 1663 $
-; $DateTime: 2014/01/19 17:59:16 $$Author: bbarber $
+; $Id: //main/2011/qhull/src/libqhull/qhull-exports.def#9 $$Change: 1951 $
+; $DateTime: 2015/08/30 21:30:30 $$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 6.3
+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_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_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
+; 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_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
-qhull_inuse DATA
rbox DATA
rbox_inuse DATA
diff --git a/src/libqhullp/qhull_p-exports.def b/src/libqhull/qhull_p-exports.def
similarity index 98%
rename from src/libqhullp/qhull_p-exports.def
rename to src/libqhull/qhull_p-exports.def
index 4235782..bdc8232 100644
--- a/src/libqhullp/qhull_p-exports.def
+++ b/src/libqhull/qhull_p-exports.def
@@ -1,415 +1,415 @@
; 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
-; Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem qhull_inuse rbox rbox_inuse
+; 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 6.3
+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_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_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_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
-qhull_inuse DATA
rbox DATA
rbox_inuse DATA
diff --git a/src/libqhull/qset.c b/src/libqhull/qset.c
index b929367..208285c 100644
--- a/src/libqhull/qset.c
+++ b/src/libqhull/qset.c
@@ -1,1339 +1,1339 @@
/*<html><pre> -<a href="qh-set.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/qset.c#9 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/qset.c#10 $$Change: 1831 $
+ $DateTime: 2015/02/07 20:31:47 $$Author: bbarber $
*/
#include "qset.h"
#include "mem.h"
#include <stdio.h>
#include <string.h>
/*** uncomment here and qhull_a.h
if string.h does not define memcpy()
#include <memory.h>
*/
#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 ===================*/
/*-<a href="qh-set.htm#TOC"
>--------------------------------<a name="setaddnth">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>--------------------------------<a name="setaddsorted">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setappend">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setappend_set">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setappend2ndlast">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setcheck">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setcompact">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setcopy">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setdel">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setdellast">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setdelnth">-</a>
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;
elemp= (setelemT *)SETelemaddr_(set, nth, void);
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);
}
lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
elem= elemp->p;
elemp->p= lastp->p; /* may overwrite itself */
lastp->p= NULL;
return elem;
} /* setdelnth */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setdelnthsorted">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setdelsorted">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setduplicate">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setendpointer">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setequal">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setequal_except">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setequal_skip">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setfree">-</a>
qh_setfree( setp )
frees the space occupied by a sorted or unsorted set
returns:
sets setp to NULL
notes:
set may be NULL
design:
free array
free set
*/
void qh_setfree(setT **setp) {
int size;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setfree2">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setfreelong">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setin">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setindex">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setlarger">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setlast">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setnew">-</a>
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 !qh_NOmem */
+ int sizereceived; /* used if !qh_NOmem */
int size;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setnew_delnthsorted">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setprint">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setreplace">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setsize">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="settemp">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="settempfree">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="settempfree_all">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="settemppop">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="settemppush">-</a>
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) {
fprintf (qhmem.ferr, "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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="settruncate">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setunique">-</a>
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 */
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="setzero">-</a>
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/libqhull/random.c b/src/libqhull/random.c
index 94be1ef..c6a3098 100644
--- a/src/libqhull/random.c
+++ b/src/libqhull/random.c
@@ -1,243 +1,245 @@
/*<html><pre> -<a href="index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
random.c -- 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 <string.h>
#include <stdio.h>
#include <stdlib.h>
#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
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="argv_to_command">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="argv_to_command_size">-</a>
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; i<argc; i++){
count += (int)strlen(argv[i]) + 1; /* WARN64 */
if (i>0 && strchr(argv[i], ' ')) {
count += 2; /* quote delimiters */
for (s=argv[i]; *s; s++) {
if (*s == '"') {
count++;
}
}
}
}
return count;
} /* argv_to_command_size */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="rand">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="randomfactor">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="randommatrix">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="strtol">-</a>
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/libqhull/rboxlib.c b/src/libqhull/rboxlib.c
index d6eea41..adca0c4 100644
--- a/src/libqhull/rboxlib.c
+++ b/src/libqhull/rboxlib.c
@@ -1,799 +1,800 @@
/*<html><pre> -<a href="index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
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 "random.h"
#include "libqhull.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <setjmp.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#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_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;
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="rboxpoints">-</a>
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 stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
Rbox is not multithreaded.
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 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 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;
+ double width=0.0, gap=0.0, radius=0.0;
double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
double *simplex= 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 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 */
+ /* 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 '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);
}
/* ============= 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;
/* ============= 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<dim; i++) {
for (k=0; k<dim; k++)
*(simplexp++)= i==k ? 1.0 : 0.0;
}
for (k=0; k<dim; k++)
*(simplexp++)= -1.0;
}else {
for (i=0; i<dim+1; i++) {
for (k=0; k<dim; k++) {
randr= qh_RANDOMint;
*(simplexp++)= 2.0 * randr/randmax - 1.0;
}
}
}
if (issimplex2) {
simplexp= simplex;
for (i=0; i<dim+1; i++) {
if (iscdd)
qh_out1( 1.0);
for (k=0; k<dim; k++)
qh_out1( *(simplexp++) * box);
qh_fprintf_rbox(rbox.fout, 9395, "\n");
}
}
for (j=0; j<numpoints; j++) {
if (iswidth)
apex= qh_RANDOMint % (dim+1);
else
apex= -1;
for (k=0; k<dim; k++)
coord[k]= 0.0;
norm= 0.0;
for (i=0; i<dim+1; i++) {
randr= qh_RANDOMint;
factor= randr/randmax;
if (i == apex)
factor *= width;
norm += factor;
for (k=0; k<dim; k++) {
simplexp= simplex + i*dim + k;
coord[k] += factor * (*simplexp);
}
}
for (k=0; k<dim; k++)
coord[k] /= norm;
if (iscdd)
qh_out1( 1.0);
for (k=0; k < dim; k++)
qh_out1( coord[k] * box);
qh_fprintf_rbox(rbox.fout, 9396, "\n");
}
isregular= 0; /* continue with isbox */
numpoints= 0;
}
/* ============= mesh distribution =============== */
if (ismesh) {
nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
for (k=dim; k--; )
mult[k]= 0;
for (i=0; i < numpoints; i++) {
for (k=0; k < dim; k++) {
if (k == 0)
qh_out1( mult[0] * meshn + mult[1] * (-meshm));
else if (k == 1)
qh_out1( mult[0] * meshm + mult[1] * meshn);
else
qh_out1( mult[k] * meshr );
}
qh_fprintf_rbox(rbox.fout, 9397, "\n");
for (k=0; k < dim; k++) {
if (++mult[k] < nthroot)
break;
mult[k]= 0;
}
}
}
/* ============= regular points for 's' =============== */
else if (isregular && !islens) {
if (dim != 2 && dim != 3) {
qh_fprintf_rbox(rbox.ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
qh_errexit_rbox(qh_ERRinput);
}
if (!isaxis || radius == 0.0) {
isaxis= 1;
radius= 1.0;
}
if (dim == 3) {
if (iscdd)
qh_out1( 1.0);
qh_out3n( 0.0, 0.0, -box);
if (!isgap) {
if (iscdd)
qh_out1( 1.0);
qh_out3n( 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( 1.0);
qh_out2n( x*box, y*box);
}else {
norm= sqrt(1.0 + x*x + y*y);
if (iscdd)
qh_out1( 1.0);
qh_out3n( 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( 1.0);
qh_out3n( 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( 1.0);
qh_out2n( x*box, y*box);
if (i != 0 && i != numpoints - 1) {
if (iscdd)
qh_out1( 1.0);
qh_out2n( x*box, -y*box);
}
}
}
/* ============= regular points for 'r Ln D3' =============== */
else if (isregular && islens && dim != 2) {
if (dim != 3) {
qh_fprintf_rbox(rbox.ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
qh_errexit_rbox(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( 1.0);
qh_out3n( box*x, box*y, 0.0);
x *= 1-gap;
y *= 1-gap;
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x, box*y, box * offset);
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x, box*y, -box * offset);
}
}
/* ============= apex of 'Zn' distribution + gendim =============== */
else {
if (isaxis) {
gendim= dim-1;
if (iscdd)
qh_out1( 1.0);
for (j=0; j < gendim; j++)
qh_out1( 0.0);
qh_out1( -box);
qh_fprintf_rbox(rbox.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; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln s' distribution =========== */
}else if (islens && issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
randr= qh_RANDOMint;
rangap= 1.0 - gap * randr/randmax;
factor= rangap / norm;
for (j=0; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln' distribution ========== */
}else if (islens && !issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * gap;
else
coord[j]= 1.0 - coord[j] * gap;
/* ============= point of 'l' distribution =============== */
}else if (isspiral) {
if (dim != 3) {
qh_fprintf_rbox(rbox.ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
- qh_errexit_rbox(qh, qh_ERRinput);
+ qh_errexit_rbox(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<dim; j++)
coord[j]= factor * coord[j];
}
/* ============= project 'Zn s' point in to sphere =============== */
if (isaxis && issphere) {
coord[dim-1]= 1.0;
norm= 1.0;
for (j=0; j<gendim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] / norm;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
/* ============= project 'Zn' point onto cube =============== */
}else if (isaxis && !issphere) { /* not very interesting */
randr= qh_RANDOMint;
coord[dim-1]= 2.0 * randr/randmax - 1.0;
/* ============= project 'Ln' point out to sphere =============== */
}else if (islens) {
coord[dim-1]= lensbase;
for (j=0, norm= 0; j<dim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] * radius/ norm;
coord[dim-1] -= lensbase;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
if (qh_RANDOMint > randmax/2)
coord[dim-1]= -coord[dim-1];
/* ============= project 'Wn' point toward boundary =============== */
}else if (iswidth && !issphere) {
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * width;
else
coord[j]= 1.0 - coord[j] * width;
}
/* ============= write point =============== */
if (iscdd)
qh_out1( 1.0);
for (k=0; k < dim; k++)
qh_out1( coord[k] * box);
qh_fprintf_rbox(rbox.fout, 9399, "\n");
}
}
/* ============= write cube vertices =============== */
if (addcube) {
for (j=0; j<cubesize; j++) {
if (iscdd)
qh_out1( 1.0);
for (k=dim-1; 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<diamondsize; j++) {
if (iscdd)
qh_out1( 1.0);
for (k=dim-1; k>=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 */
if (simplex)
qh_free(simplex);
rbox_inuse= False;
return qh_ERRnone;
} /* rboxpoints */
/*------------------------------------------------
outxxx - output functions
*/
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 */
/*------------------------------------------------
Only called from qh_rboxpoints or qh_fprintf_rbox (which is only called from qh_rboxpoints)
*/
void qh_errexit_rbox(int exitcode)
{
longjmp(rbox.errexit, exitcode);
} /* rbox_errexit */
diff --git a/src/libqhull/stat.c b/src/libqhull/stat.c
index e0e4074..1a3fa2b 100644
--- a/src/libqhull/stat.c
+++ b/src/libqhull/stat.c
@@ -1,716 +1,717 @@
/*<html><pre> -<a href="qh-stat.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhull/stat.c#6 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull/stat.c#8 $$Change: 1835 $
+ $DateTime: 2015/02/16 22:32:04 $$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 ================*/
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="allstatA">-</a>
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_(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 */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="allstatistics">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="collectstatistics">-</a>
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 */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="freestatistics">-</a>
qh_freestatistics( )
free memory used for statistics
*/
void qh_freestatistics(void) {
#if qh_QHpointer
qh_free(qh_qhstat);
qh_qhstat= NULL;
#endif
} /* freestatistics */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="initstatistics">-</a>
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.
+ 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)))) {
fprintf(qhmem.ferr, "QH6183 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 */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="newstats">-</a>
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 */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="nostatistic">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printallstatistics">-</a>
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);
}
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printstatistics">-</a>
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 */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printstatlevel">-</a>
qh_printstatlevel( fp, id )
print level information for a statistic
notes:
nop if id >= ZEND, printed, or same as initial value
*/
-void qh_printstatlevel(FILE *fp, int id, int start) {
+void qh_printstatlevel(FILE *fp, int id, int start) { /* start not used */
#define NULLfield " "
+ QHULL_UNUSED(start)
if (id >= ZEND || qhstat printed[id])
return;
if (qhstat type[id] == zdoc) {
qh_fprintf(fp, 9360, "%s\n", qhstat doc[id]);
return;
}
start= 0; /* not used */
if (qh_nostatistic(id) || !qhstat doc[id])
return;
qhstat printed[id]= True;
if (qhstat count[id] != -1
&& qhstat stats[(unsigned char)(qhstat count[id])].i == 0)
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 */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printstats">-</a>
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<nexti; j++)
qh_printstatlevel(fp, qhstat id[j], 0);
}
if (nextindex)
*nextindex= nexti;
} /* printstats */
#if qh_KEEPstatistics
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="stddev">-</a>
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/libqhull/user.c b/src/libqhull/user.c
index 7249843..5f747f1 100644
--- a/src/libqhull/user.c
+++ b/src/libqhull/user.c
@@ -1,528 +1,535 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
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, unix.c, and qhull_interface.cpp for examples.
see user.h for user-definable constants
use qh_NOmem in mem.h to turn off memory management
use qh_NOmerge in user.h to turn off facet merging
set qh_KEEPstatistics in user.h to 0 to turn off statistics
This is unsupported software. You're welcome to make changes,
but you're on your own if something goes wrong. Use 'Tc' to
check frequently. Usually qhull will report an error if
a data structure becomes inconsistent. If so, it also reports
the last point added to the hull, e.g., 102. You can then trace
the execution of qhull with "T4P102".
Please report any errors that you fix to qhull@qhull.org
call_qhull is a template for calling qhull from within your application
if you recompile and load this module, then user.o will not be loaded
from qhull.a
you can add additional quick allocation sizes in qh_user_memsizes
if the other functions here are redefined to not use qh_print...,
then io.o will not be loaded from qhull.a. See user_eg.c for an
example. We recommend keeping io.o for the extra debugging
information it supplies.
*/
#include "qhull_a.h"
#include <stdarg.h>
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="call_qhull">-</a>
qh_call_qhull( void )
template for calling qhull from inside your program
remove #if 0, #endif to compile
returns:
exit code(see qh_ERR... in libqhull.h)
all memory freed
notes:
This can be called any number of times.
see:
qh_call_qhull_once()
*/
#if 0
{
int dim; /* dimension of points */
int numpoints; /* number of points */
coordT *points; /* array of coordinates for each point */
boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
FILE *outfile= stdout; /* output from qh_produce_output()
use NULL to skip qh_produce_output() */
FILE *errfile= stderr; /* error messages from qhull code */
int exitcode; /* 0 if no error from qhull */
facetT *facet; /* set by FORALLfacets */
int curlong, totlong; /* memory remaining after qh_memfreeshort */
+ QHULL_LIB_CHECK
+
#if qh_QHpointer /* see user.h */
if (qh_qh){
printf ("QH6238: 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
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="new_qhull">-</a>
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().
- outfile may be null
+ errfile must be defined, outfile may be null
qhull_cmd must start with "qhull "
projects points to a new point array for Delaunay triangulations ('d' and 'v')
transforms points into a new point array for halfspace intersection ('H')
To allow multiple, concurrent calls to qhull()
- set qh_QHpointer in user.h
- use qh_save_qhull and qh_restore_qhull to swap the global data structure between calls.
- use qh_freeqhull(qh_ALL) to free intermediate convex hulls
see:
user_eg.c for an example
*/
int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
char *qhull_cmd, FILE *outfile, FILE *errfile) {
int exitcode, hulldim;
boolT new_ismalloc;
static boolT firstcall = True;
coordT *new_points;
if (firstcall) {
qh_meminit(errfile);
firstcall= False;
}
if (strncmp(qhull_cmd,"qhull ", (size_t)6)) {
qh_fprintf(errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
qh_exit(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 */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="errexit">-</a>
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. Exit program\n");
+ 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 */
+ qh ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
longjmp(qh errexit, exitcode);
} /* errexit */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="errprint">-</a>
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 */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="printfacetlist">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhelp_degenerate">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="printhelp_narrowhull">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhelp_singular">-</a>
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, -1);
+ 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="user_memsizes">-</a>
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/libqhull/user.h b/src/libqhull/user.h
index 0a162e2..48f5cbc 100644
--- a/src/libqhull/user.h
+++ b/src/libqhull/user.h
@@ -1,859 +1,861 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
user.h
user redefinable constants
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 <time.h>
#ifndef qhDEFuser
#define qhDEFuser 1
/*============================================================*/
/*============= qhull library constants ======================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="filenamelen">-</a>
FILENAMElen -- max length for TI and TO filenames
*/
#define qh_FILENAMElen 500
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="msgcode">-</a>
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, 1047, 2059, 3025, 4068, 5003,
- 6243, 7079, 8143, 9410, 10000, 11026]
+ def counters = [27, 1048, 2059, 3025, 4068, 5003,
+ 6260, 7079, 8143, 9410, 10000, 11026]
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 */
#define MSG_FIXUP 11000 /* FIXUP QH11... */
#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="qh_OPTIONline">-</a>
qh_OPTIONline -- max length of an option line 'FO'
*/
#define qh_OPTIONline 80
/*============================================================*/
/*============= data types and configuration macros ==========*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="realT">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="CPUclock">-</a>
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,
<time.h> 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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="RANDOM">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="ORIENTclock">-</a>
qh_ORIENTclock
0 for inward pointing normals by Geomview convention
*/
#define qh_ORIENTclock 0
/*============================================================*/
/*============= joggle constants =============================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEdefault">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEincrease">-</a>
qh_JOGGLEincrease
factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
*/
#define qh_JOGGLEincrease 10.0
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEretry">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEagain">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxincrease">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxretry">-</a>
qh_JOGGLEmaxretry
stop after qh_JOGGLEmaxretry attempts
*/
#define qh_JOGGLEmaxretry 100
/*============================================================*/
/*============= performance related constants ================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="HASHfactor">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="VERIFYdirect">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INITIALsearch">-</a>
qh_INITIALsearch
if qh_INITIALmax, search points up to this dimension
*/
#define qh_INITIALsearch 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INITIALmax">-</a>
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 =============================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMalign">-</a>
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 *))))
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMbufsize">-</a>
qh_MEMbufsize
size of additional memory buffers
notes:
used for qh_meminitbuffers() in global.c
*/
#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMinitbuf">-</a>
qh_MEMinitbuf
size of initial memory buffer
notes:
use for qh_meminitbuffers() in global.c
*/
#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INFINITE">-</a>
qh_INFINITE
on output, indicates Voronoi center at infinity
*/
#define qh_INFINITE -10.101
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DEFAULTbox">-</a>
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 ======================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="compiler">-</a>
__cplusplus
defined by C++ compilers
__MSC_VER
defined by Microsoft Visual C++
__MWERKS__ && __POWERPC__
defined by Metrowerks when compiling for the Power Macintosh
__STDC__
defined for strict ANSI C
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="COMPUTEfurthest">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
=0 removes most of statistic gathering and reporting
notes:
if 0, code size is reduced by about 4%.
*/
#define qh_KEEPstatistics 1
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXoutside">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="NOmerge">-</a>
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:
<a href="mem.h#NOmem">qh_NOmem</a> in mem.c
see user.c/user_eg.c for removing io.o
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="NOtrace">-</a>
qh_NOtrace
no tracing if defined
notes:
This saves about 5% space.
#define qh_NOtrace
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="QHpointer">-</a>
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:
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
C++ build defines qh_QHpointer [libqhullp.pro, libqhullcpp.pro]
see:
user_eg.c for an example
*/
#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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="QUICKhelp">-</a>
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.
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DIMmergeVertex">-</a>
qh_DIMmergeVertex
max dimension for vertex merging (it is not effective in high-d)
*/
#define qh_DIMmergeVertex 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DIMreduceBuild">-</a>
qh_DIMreduceBuild
max dimension for vertex reduction during build (slow in high-d)
*/
#define qh_DIMreduceBuild 5
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="BESTcentrum">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="BESTnonconvex">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnewmerges">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnewcentrum">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="COPLANARratio">-</a>
qh_COPLANARratio
for 3-d+ merging, qh.MINvisible is n*premerge_centrum
notes:
for non-merging, it's DISTround
*/
#define qh_COPLANARratio 3
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DISToutside">-</a>
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))
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="RATIOnearinside">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="SEARCHdist">-</a>
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)));
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="USEfindbestnew">-</a>
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)
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WIDEcoplanar">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnarrow">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WARNnarrow">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="ZEROdelaunay">-</a>
qh_ZEROdelaunay
a zero Delaunay facet occurs for input sites coplanar with their convex hull
the last normal coefficient of a zero Delaunay facet is within
qh_ZEROdelaunay * qh.ANGLEround of 0
notes:
qh_ZEROdelaunay does not allow for joggled input ('QJ').
You can avoid zero Delaunay facets by surrounding the input with a box.
Use option 'PDk:-n' to explicitly define zero Delaunay facets
k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
*/
#define qh_ZEROdelaunay 2
#endif /* qh_DEFuser */
diff --git a/src/libqhull/usermem.c b/src/libqhull/usermem.c
index 5794c91..a2d4093 100644
--- a/src/libqhull/usermem.c
+++ b/src/libqhull/usermem.c
@@ -1,64 +1,65 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
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 <stdlib.h>
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_exit">-</a>
qh_exit( exitcode )
exit program
notes:
same as exit()
*/
void qh_exit(int exitcode) {
exit(exitcode);
} /* exit */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_free">-</a>
qh_free( mem )
free memory
notes:
same as free()
+ No calls to qh_errexit()
*/
void qh_free(void *mem) {
free(mem);
} /* free */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_malloc">-</a>
qh_malloc( mem )
allocate memory
notes:
same as malloc()
*/
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */
diff --git a/src/libqhull_r/Makefile b/src/libqhull_r/Makefile
new file mode 100644
index 0000000..efb5048
--- /dev/null
+++ b/src/libqhull_r/Makefile
@@ -0,0 +1,227 @@
+# Simple gcc Makefile for reentrant qhull and rbox (default gcc/g++)
+#
+# see README.txt
+#
+# Results
+# qhull Computes convex hulls and related structures
+# qconvex, qdelaunay, qhalf, qvoronoi
+# Specializations of qhull for each geometric structure
+# rbox Input generator for qhull, qconvex, etc.
+# user_eg An example of using qhull (reentrant)
+# user_eg2 An example of using qhull (reentrant)
+# testqset_r Standalone test of reentrant qset_r.c with mem_r.c
+# libqhullstatic_r.a Static library for reentrant qhull
+#
+# Make targets
+# make Produce all of the results
+# make help Help message
+# make test Quck test of qhull, qconvex, etc.
+# make qtest Quick test of qset, rbox, and qhull
+# make doc Print documentation
+# make install Copy qhull, rbox, qhull.1, rbox_r.1 to BINDIR, MANDIR
+# make new Rebuild qhull and rbox from source
+#
+# make printall Print all files
+# make clean Remove object files
+# make cleanall Remove generated files
+#
+# 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
+#
+# Do not replace tabs with spaces. Needed by 'make' for build rules
+
+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
+# -fPIC needed for gcc x86_64-linux-gnu. Not needed for mingw
+CC = gcc
+CC_OPTS1 = -O3 -ansi -Isrc -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..
+
+# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
+#CC = cc
+#CC_OPTS1 = -ansi -O2 -I..
+
+# for Next cc compiler with fat executable
+#CC = cc
+#CC_OPTS1 = -ansi -O2 -I.. -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 52 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 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
+
+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/libqhullr/geom2_r.c b/src/libqhull_r/geom2_r.c
similarity index 98%
rename from src/libqhullr/geom2_r.c
rename to src/libqhull_r/geom2_r.c
index 871d9be..9cdd43c 100644
--- a/src/libqhullr/geom2_r.c
+++ b/src/libqhull_r/geom2_r.c
@@ -1,2081 +1,2082 @@
/*<html><pre> -<a href="qh-geom.htm"
>-------------------------------</a><a name="TOP">-</a>
geom2_r.c
infrequently used geometric routines of qhull
see qh-geom.htm and geom_r.h
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/geom2_r.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/geom2_r.c#3 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
frequently used code goes into geom_r.c
*/
#include "qhull_ra.h"
/*================== functions in alphabetic order ============*/
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="copypoints">-</a>
qh_copypoints(qh, points, numpoints, dimension)
return qh_malloc'd copy of points
*/
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);
return newpoints;
} /* copypoints */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="crossproduct">-</a>
- qh_crossproduct(qh, dim, vecA, vecB, vecC )
+ 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(qhT *qh, int dim, realT vecA[3], realT vecB[3], realT vecC[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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="determinant">-</a>
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) < qh->NEARzero[1]) /* not really correct, what should this be? */
*nearzero= True;
}else if (dim == 3) {
det= det3_(rows[0][0], rows[0][1], rows[0][2],
rows[1][0], rows[1][1], rows[1][2],
rows[2][0], rows[2][1], rows[2][2]);
if (fabs_(det) < qh->NEARzero[2]) /* not really correct, what should this be? */
*nearzero= True;
}else {
qh_gausselim(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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="detjoggle">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="detroundoff">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="detsimplex">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="distnorm">-</a>
- qh_distnorm(qh, dim, point, normal, offset )
+ 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(qhT *qh, int dim, pointT *point, pointT *normal, realT *offsetp) {
+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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="distround">-</a>
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
Lemma 3.2-1 of Golub and van Loan "Matrix Computation"
use sqrt(dim) since one vector is normalized
or use maxsumabs since one vector is < 1
*/
realT qh_distround(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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="divzero">-</a>
- qh_divzero(qh, numer, denom, mindenom1, zerodiv )
+ 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(qhT *qh, realT numer, realT denom, realT mindenom1, boolT *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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="facetarea">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="facetarea_simplex">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="facetcenter">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="findgooddist">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="getarea">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="gram_schmidt">-</a>
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 Algorithm 6.2-2
overflow due to small divisors not handled
design:
for each row
compute norm for row
if non-zero, normalize row
for each remaining rowA
compute inner product of row and rowA
reduce rowA by row * inner product
*/
boolT qh_gram_schmidt(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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="inthresholds">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="joggleinput">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="maxabsval">-</a>
- qh_maxabsval(qh, normal, dim )
+ qh_maxabsval( normal, dim )
return pointer to maximum absolute value of a dim vector
returns NULL if dim=0
*/
-realT *qh_maxabsval(qhT *qh, realT *normal, int dim) {
+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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="maxmin">-</a>
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 error formula 4.4-13 of
Golub & van Loan, authors say n^3 can be ignored and 10 be used in
place of rho */
qh->NEARzero[k]= 80 * qh->MAXsumcoord * REALepsilon;
}
if (qh->IStracing >=1)
qh_printpoints(qh, qh->ferr, "qh_maxmin: found the max and min points(by dim):", set);
return(set);
} /* maxmin */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="maxouter">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="maxsimplex">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="minabsval">-</a>
- qh_minabsval(qh, normal, dim )
+ qh_minabsval( normal, dim )
return minimum absolute value of a dim vector
*/
-realT qh_minabsval(qhT *qh, realT *normal, int dim) {
+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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="mindiff">-</a>
qh_mindif(qh, vecA, vecB, dim )
return index of min abs. difference of two vectors
*/
-int qh_mindiff(qhT *qh, realT *vecA, realT *vecB, int dim) {
+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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="orientoutside">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="outerinner">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="pointdist">-</a>
- qh_pointdist(qh, point1, point2, dim )
+ qh_pointdist( point1, point2, dim )
return distance between two points
notes:
returns distance squared if 'dim' is negative
*/
-coordT qh_pointdist(qhT *qh, pointT *point1, pointT *point2, int dim) {
+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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="printmatrix">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="printpoints">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="projectinput">-</a>
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 size= (qh->input_dim+1)*sizeof(*project);
pointT *newpoints, *coord, *infinity;
realT paraboloid, maxboloid= 0;
project= (signed char*)qh_memalloc(qh, size);
memset((char*)project, 0, (size_t)size);
for (k=0; k < qh->input_dim; k++) { /* skip Delaunay bound */
if (qh->lower_bound[k] == 0 && qh->upper_bound[k] == 0) {
project[k]= -1;
newdim--;
}
}
if (qh->DELAUNAY) {
project[k]= 1;
newdim++;
if (qh->ATinfinity)
newnum++;
}
if (newdim != qh->hull_dim) {
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=(coordT*)qh_malloc(newnum*newdim*sizeof(coordT)))){
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(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_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, (qh->input_dim+1)*sizeof(*project));
if (qh->POINTSmalloc)
qh_free(qh->first_point);
qh->first_point= newpoints;
qh->POINTSmalloc= True;
if (qh->DELAUNAY && qh->ATinfinity) {
coord= qh->first_point;
infinity= qh->first_point + qh->hull_dim * qh->num_points;
for (k=qh->hull_dim-1; k--; )
infinity[k]= 0.0;
for (i=qh->num_points; i--; ) {
paraboloid= 0.0;
for (k=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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="projectpoints">-</a>
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<n; j++) {
if (project[j] == -1)
oldk++;
else {
newp= newpoints+newk++;
if (project[j] == +1) {
if (oldk >= 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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="rotateinput">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="rotatepoints">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="scaleinput">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="scalelast">-</a>
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(qh, newhigh, high - low,
+ 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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="scalepoints">-</a>
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(qh, newhigh - newlow, high - low,
+ 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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="setdelaunay">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="sethalfspace">-</a>
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 if feasible point is outside of hull (error message already reported)
overwrites coordinates for point at dim coords
nextp= next point (coords)
design:
compute distance from feasible point to halfspace
divide each normal coefficient by -dist
*/
boolT qh_sethalfspace(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(qh, *(normp++), -dist, qh->MINdenom_1, &zerodiv);
+ *(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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="sethalfspace_all">-</a>
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
returns:
malloc'd array of count X dim-1 points
notes:
call before qh_init_B or qh_initqhull_globals
unused/untested code: please email bradb@shore.net if this works ok for you
If using option 'Fp', also set qh->feasible_point. It is a malloc'd array
that is freed by qh_freebuffers.
design:
see qh_sethalfspace
*/
coordT *qh_sethalfspace_all(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_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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="sharpnewfacets">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="voronoi_center">-</a>
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
if non-simplicial,
returns center for max simplex of points
notes:
from Bowyer & Woodwark, A Programmer's Geometry, 1983, p. 65
design:
if non-simplicial
determine max simplex for points
translate point0 of simplex to origin
compute sum of squares of diagonal
compute determinate
compute Voronoi center (see Bowyer & Woodwark)
*/
pointT *qh_voronoi_center(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_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(qh, 0.5, det, qh->MINdenom, &infinite);
+ 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, 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:", &center, 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(qh, point, center, dim));
+ 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/libqhullr/geom_r.c b/src/libqhull_r/geom_r.c
similarity index 96%
rename from src/libqhullr/geom_r.c
rename to src/libqhull_r/geom_r.c
index 6c8a93b..bd5aa46 100644
--- a/src/libqhullr/geom_r.c
+++ b/src/libqhull_r/geom_r.c
@@ -1,1234 +1,1234 @@
-/*<html><pre> -<a href="qh-geom.htm"
+/*<html><pre> -<a href="qh-geom_r.htm"
>-------------------------------</a><a name="TOP">-</a>
geom_r.c
geometric routines of qhull
- see qh-geom.htm and geom_r.h
+ see qh-geom_r.htm and geom_r.h
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/geom_r.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/geom_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
infrequent code goes into geom2_r.c
*/
#include "qhull_ra.h"
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="distplane">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="findbest">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="findbesthorizon">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="findbestnew">-</a>
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)
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 [?] ============ */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="backnormal">-</a>
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 4.4-9 for back substitution
solves Ux=b where Ax=b and PA=LU
b= [0,...,0,sign or 0] (sign is either -1 or +1)
last row of A= [0,...,0,1]
1) Ly=Pb == y=b since P only permutes the 0's of b
design:
for each row from end
perform back substitution
if near zero
use qh_divzero for division
if zero divide and not last row
set tail of normal to 0
*/
void qh_backnormal(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(qh, *normalp, diagonal, qh->MINdenom_1_2, &waszero);
+ *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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="gausselim">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="getangle">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="getcenter">-</a>
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;
}
return(center);
} /* getcenter */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="getcentrum">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="getdistance">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="normalize">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="normalize2">-</a>
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(qh, *colp, norm, qh->MINdenom_1, &zerodiv);
+ temp= qh_divzero(*colp, norm, qh->MINdenom_1, &zerodiv);
if (!zerodiv)
*colp= temp;
else {
- maxp= qh_maxabsval(qh, normal, dim);
+ 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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="projectpoint">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="setfacetplane">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="sethyperplane_det">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="sethyperplane_gauss">-</a>
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/libqhullr/geom_r.h b/src/libqhull_r/geom_r.h
similarity index 91%
rename from src/libqhullr/geom_r.h
rename to src/libqhull_r/geom_r.h
index cc571d1..8a0bcd7 100644
--- a/src/libqhullr/geom_r.h
+++ b/src/libqhull_r/geom_r.h
@@ -1,176 +1,176 @@
/*<html><pre> -<a href="qh-geom.htm"
>-------------------------------</a><a name="TOP">-</a>
geom_r.h
header file for geometric routines
see qh-geom.htm and geom_r.c
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/geom_r.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/geom_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFgeom
#define qhDEFgeom 1
#include "libqhull_r.h"
/* ============ -macros- ======================== */
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="fabs_">-</a>
fabs_(a)
returns the absolute value of a
*/
#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="fmax_">-</a>
fmax_(a,b)
returns the maximum value of a and b
*/
#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="fmin_">-</a>
fmin_(a,b)
returns the minimum value of a and b
*/
#define fmin_( a,b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="maximize_">-</a>
maximize_(maxval, val)
set maxval to val if val is greater than maxval
*/
#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); }
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="minimize_">-</a>
minimize_(minval, val)
set minval to val if val is less than minval
*/
#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); }
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="det2_">-</a>
det2_(a1, a2,
b1, b2)
compute a 2-d determinate
*/
#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="det3_">-</a>
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 ) )
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="dX">-</a>
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(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(qhT *qh, int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
+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(qhT *qh, int dim, pointT *point, pointT *normal, realT *offsetp);
+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(qhT *qh, realT numer, realT denom, realT mindenom1, boolT *zerodiv);
+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(qhT *qh, realT *normal, int dim);
+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(qhT *qh, realT *normal, int dim);
-int qh_mindiff(qhT *qh, realT *vecA, realT *vecB, int dim);
+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(qhT *qh, pointT *point1, pointT *point2, int dim);
+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);
#endif /* qhDEFgeom */
diff --git a/src/libqhullr/global_r.c b/src/libqhull_r/global_r.c
similarity index 94%
rename from src/libqhullr/global_r.c
rename to src/libqhull_r/global_r.c
index 61d20b6..ae138ff 100644
--- a/src/libqhullr/global_r.c
+++ b/src/libqhull_r/global_r.c
@@ -1,2007 +1,2075 @@
/*<html><pre> -<a href="qh-globa.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhullr/global_r.c#10 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/global_r.c#3 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*========= qh->definition -- globals defined in libqhull_r.h =======================*/
/*-<a href ="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh_version">-</a>
qh_version
version string by year and date
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
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 = "2012.1 2012/02/18";
+const char *qh_version = "2015.0.2.r 2015/08/30";
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="appendprint">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="checkflags">-</a>
qh_checkflags(qh, commandStr, hiddenFlags )
errors if commandStr contains hiddenFlags
- hiddenFlags starts and ends with a space and is space deliminated (checked)
+ 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="qh_clear_outputflags">-</a>
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_ouputflags */
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="clock">-</a>
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 */
+ 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freebuffers">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freebuild">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freeqhull">-</a>
qh_freeqhull(qh, allmem )
free global memory
if !allmem,
does not free short memory (freed by qh_memfreeshort)
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_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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_A">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_B">-</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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_qhull_command">-</a>
qh_init_qhull_command(qh, argc, argv )
build qh.qhull_command from argc/argv
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initflags">-</a>
qh_initflags(qh, commandStr )
set flags and initialized constants from commandStr
returns:
sets qh.qhull_command to command if needed
notes:
ignores first word (e.g., "qhull d")
use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
see:
qh_initthresholds() continues processing of 'Pdn' and 'PDn'
'prompt' in unix_r.c for documentation
design:
- for each space-deliminated option group
+ for each space-delimited option group
if top-level option
check syntax
- append approriate option to option string
+ append appropriate option to option string
set appropriate global variable or append printFormat to print options
else
for each sub-option
check syntax
- append approriate option to option string
+ 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 error: qh.NOerrexit not cleared after setjmp() and before qh_initflags(). Exiting with error.");
+ 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;
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 (!freopen(filename, "w", stdout)) {
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_buffers">-</a>
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_ouputflags */
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_globals">-</a>
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 != -1 || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
+ }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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_mem">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_outputflags">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_start">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initqhull_start2">-</a>
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= -1;
+ 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= -1; /* recompile or use 'TPn' */
+ 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="initthresholds">-</a>
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 */
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="lib_check">-</a>
+
+ qh_lib_check( isQHpointer, 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 libraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
+ boolT iserror= False;
+
+ if (libraryType==0) {
+ qh_fprintf(NULL, 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 (libraryType==1) {
+ qh_fprintf(NULL, 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;
+ }
+ if (qhTsize != sizeof(qhT)) {
+ qh_fprintf(NULL, 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(NULL, 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(NULL, 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(NULL, 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(NULL, 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(NULL, 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(NULL, stderr, 6259, "qh_lib_check: Cannot continue. Library '%s' is reentrant (e.g., qhull_r.so)\n", qh_version);
+ qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
+ }
+} /* lib_check */
+
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="option">-</a>
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 */
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="zero">-</a>
+
+ 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/libqhullr/index.htm b/src/libqhull_r/index.htm
similarity index 76%
rename from src/libqhullr/index.htm
rename to src/libqhull_r/index.htm
index 15f84b8..3e0fdef 100644
--- a/src/libqhullr/index.htm
+++ b/src/libqhull_r/index.htm
@@ -1,248 +1,247 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>Qhull functions, macros, and data structures</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code</a><br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
<hr>
<!-- Main text of document. -->
<h1>Qhull functions, macros, and data structures</h1>
<blockquote>
<p>The following sections provide an overview and index to
Qhull's functions, macros, and data structures. Each
section starts with an introduction. If you use Opera, the source code links back to this documentation.
See also <a href=../../html/qh-code.htm#library>Calling
Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
<p>Qhull uses the following conventions:</p>
<blockquote>
<ul>
<li>in code, global variables start with &quot;qh &quot;
<li>in documentation, global variables start with 'qh.'
<li>constants start with an upper case word
<li>important globals include an '_'
<li>functions, macros, and constants start with &quot;qh_&quot;</li>
<li>data types end in &quot;T&quot;</li>
<li>macros with arguments end in &quot;_&quot;</li>
<li>iterators are macros that use local variables</li>
<li>iterators for sets start with &quot;FOREACH&quot;</li>
<li>iterators for lists start with &quot;FORALL&quot;</li>
<li>qhull options are in single quotes (e.g., 'Pdn')</li>
<li>lists are sorted alphabetically</li>
<li>preprocessor directives on left margin for older compilers</li>
</ul>
</blockquote>
<p>
When reading the code, please note that the
global data structure, 'qh', is a macro. It
either expands to &quot;qh_qh.&quot; or to
&quot;qh_qh-&gt;&quot;. The later is used for
applications which run concurrent calls to qh_qhull().
<p>
When reading code with an editor, a search for
<i>&quot;procedure</i>
will locate the header of <i>qh_procedure</i>. A search for <i>* procedure</i>
will locate the tail of <i>qh_procedure</i>.
-<p>A useful starting point is <a href="libqhull.h">libqhull.h</a>. It defines most
+<p>A useful starting point is <a href="libqhull_r.h">libqhull_r.h</a>. It defines most
of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
-determine the corresponding <a href="libqhull.h#qh_PRINT">qh_PRINT...</a> constant.
-Search <a href="io.c">io.c</a> to learn how the print function is implemented.</p>
+determine the corresponding <a href="libqhull_r.h#qh_PRINT">qh_PRINT...</a> constant.
+Search <a href="io.c">io_r.c</a> to learn how the print function is implemented.</p>
<p>If your web browser loads .c and .h files with an external application,
change the MIME type of .c and .h files to "text/html".
Opera does not always work since it treats '&lt;' characters as HTML tags.
<p>
Please report documentation and link errors
to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
</blockquote>
<p><b>Copyright &copy; 1997-2015 C.B. Barber</b></p>
<hr>
<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull files</a> </h2>
<blockquote>
<p>This sections lists the .c and .h files for Qhull. Please
refer to these files for detailed information.</p>
<blockquote>
<dl>
<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
platforms with <a href=http://www.cmake.org/>CMake</a>.
Qhull includes project files for Visual Studio and Qt.
</dd>
<dt>&nbsp;</dt>
-<dt><a href="libqhull.h"><b>libqhull.h</b></a> </dt>
+<dt><a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
Data structures are documented under <a href="qh-poly.htm">Poly</a>.
Global variables are documented under <a href="qh-globa.htm">Global</a>.
Other data structures and variables are documented under
<a href="qh-qhull.htm#TOC">Qhull</a> or <a href="qh-geom.htm"><b>Geom</b></a><b>.</b></dd>
<dt>&nbsp;</dt>
<dt><a href="qh-geom.htm"><b>Geom</b></a><b>, </b>
-<a href="geom.h"><b>geom.h</b></a><b>, </b>
-<a href="geom.c"><b>geom.c</b></a><b>, </b>
-<a href="geom2.c"><b>geom2.c</b></a><b>, </b>
-<a href="random.c"><b>random.c</b></a><b>, </b>
-<a href="random.h"><b>random.h</b></a></dt>
+<a href="geom_r.h"><b>geom_r.h</b></a><b>, </b>
+<a href="geom_r.c"><b>geom_r.c</b></a><b>, </b>
+<a href="geom2_r.c"><b>geom2_r.c</b></a><b>, </b>
+<a href="random_r.c"><b>random_r.c</b></a><b>, </b>
+<a href="random_r.h"><b>random_r.h</b></a></dt>
<dd>Geometric routines. These routines implement mathematical
functions such as Gaussian elimination and geometric
routines needed for Qhull. Frequently used routines are
-in <tt>geom.c</tt> while infrequent ones are in <tt>geom2.c</tt>.
+in <tt>geom_r.c</tt> while infrequent ones are in <tt>geom2_r.c</tt>.
</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-globa.htm"><b>Global</b></a><b>, </b>
-<a href="global.c"><b>global.c</b></a><b>, </b>
-<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
+<a href="global_r.c"><b>global_r.c</b></a><b>, </b>
+<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
to store globally defined constants, lists, sets, and
variables.
-<tt>global.c</tt> initializes and frees these
+<tt>global_r.c</tt> initializes and frees these
structures. </dd>
<dt>&nbsp;</dt>
-<dt><a href="qh-io.htm"><b>Io</b></a><b>, </b><a href="io.h"><b>io.h</b></a><b>,
-</b><a href="io.c"><b>io.c</b></a> </dt>
+<dt><a href="qh-io.htm"><b>Io</b></a><b>, </b><a href="io_r.h"><b>io_r.h</b></a><b>,
+</b><a href="io_r.c"><b>io_r.c</b></a> </dt>
<dd>Input and output routines. Qhull provides a wide range of
input and output options.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-mem.htm"><b>Mem</b></a><b>, </b>
-<a href="mem.h"><b>mem.h</b></a><b>, </b>
-<a href="mem.c"><b>mem.c</b></a> </dt>
+<a href="mem_r.h"><b>mem_r.h</b></a><b>, </b>
+<a href="mem_r.c"><b>mem_r.c</b></a> </dt>
<dd>Memory routines. Qhull provides memory allocation and
deallocation. It uses quick-fit allocation.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-merge.htm"><b>Merge</b></a><b>, </b>
-<a href="merge.h"><b>merge.h</b></a><b>, </b>
-<a href="merge.c"><b>merge.c</b></a> </dt>
+<a href="merge_r.h"><b>merge_r.h</b></a><b>, </b>
+<a href="merge_r.c"><b>merge_r.c</b></a> </dt>
<dd>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.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-poly.htm"><b>Poly</b></a><b>, </b>
-<a href="poly.h"><b>poly.h</b></a><b>, </b>
-<a href="poly.c"><b>poly.c</b></a><b>, </b>
-<a href="poly2.c"><b>poly2.c</b></a><b>, </b>
-<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
+<a href="poly_r.h"><b>poly_r.h</b></a><b>, </b>
+<a href="poly_r.c"><b>poly_r.c</b></a><b>, </b>
+<a href="poly2_r.c"><b>poly2_r.c</b></a><b>, </b>
+<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
<dd>Polyhedral routines. Qhull produces a polyhedron as a
list of facets with vertices, neighbors, ridges, and
-geometric information. <tt>libqhull.h</tt> defines the main
-data structures. Frequently used routines are in <tt>poly.c</tt>
-while infrequent ones are in <tt>poly2.c</tt>.</dd>
+geometric information. <tt>libqhull_r.h</tt> defines the main
+data structures. Frequently used routines are in <tt>poly_r.c</tt>
+while infrequent ones are in <tt>poly2_r.c</tt>.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-qhull.htm#TOC"><b>Qhull</b></a><b>, </b>
-<a href="libqhull.c"><b>libqhull.c</b></a><b>, </b>
-<a href="libqhull.h"><b>libqhull.h</b></a><b>, </b>
-<a href="qhull_a.h"><b>qhull_a.h</b></a><b>, </b>
-<a href="../qhull/unix.c"><b>unix.c</b></a> <b>, </b>
-<a href="../qconvex/qconvex.c"><b>qconvex.c</b></a> <b>, </b>
-<a href="../qdelaunay/qdelaun.c"><b>qdelaun.c</b></a> <b>, </b>
-<a href="../qhalf/qhalf.c"><b>qhalf.c</b></a> <b>, </b>
-<a href="../qvoronoi/qvoronoi.c"><b>qvoronoi.c</b></a> </dt>
+<a href="libqhull_r.c"><b>libqhull_r.c</b></a><b>, </b>
+<a href="libqhull_r.h"><b>libqhull_r.h</b></a><b>, </b>
+<a href="qhull_ra.h"><b>qhull_ra.h</b></a><b>, </b>
+<a href="../qhull/unix_r.c"><b>unix_r.c</b></a> <b>, </b>
+<a href="../qconvex/qconvex_r.c"><b>qconvex_r.c</b></a> <b>, </b>
+<a href="../qdelaunay/qdelaun_r.c"><b>qdelaun_r.c</b></a> <b>, </b>
+<a href="../qhalf/qhalf_r.c"><b>qhalf_r.c</b></a> <b>, </b>
+<a href="../qvoronoi/qvoronoi_r.c"><b>qvoronoi_r.c</b></a> </dt>
<dd>Top-level routines. The Quickhull algorithm is
-implemented by <tt>libqhull.c</tt>. <tt>qhull_a.h</tt>
+implemented by <tt>libqhull_r.c</tt>. <tt>qhull_ra.h</tt>
includes all header files. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-set.htm"><b>Set</b></a><b>, </b>
-<a href="qset.h"><b>qset.h</b></a><b>, </b>
-<a href="qset.c"><b>qset.c</b></a> </dt>
+<a href="qset_r.h"><b>qset_r.h</b></a><b>, </b>
+<a href="qset_r.c"><b>qset_r.c</b></a> </dt>
<dd>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. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-stat.htm"><b>Stat</b></a><b>, </b>
-<a href="stat.h"><b>stat.h</b></a><b>, </b>
-<a href="stat.c"><b>stat.c</b></a> </dt>
+<a href="stat_r.h"><b>stat_r.h</b></a><b>, </b>
+<a href="stat_r.c"><b>stat_r.c</b></a> </dt>
<dd>Statistical routines. Qhull maintains statistics about
its implementation. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-user.htm"><b>User</b></a><b>, </b>
-<a href="user.h"><b>user.h</b></a><b>, </b>
-<a href="user.c"><b>user.c</b></a><b>, </b>
-<a href="../user_eg/user_eg.c"><b>user_eg.c</b></a><b>, </b>
-<a href="../user_eg2/user_eg2.c"><b>user_eg2.c</b></a><b>, </b>
-<a href="../user_eg3/user_eg3.cpp"><b>user_eg3.cpp</b></a><b>, </b>
-<a href="../libqhullcpp/qhull_interface.cpp#TOP"><b>qhull_interface.cpp</b></a></dt>
+<a href="user_r.h"><b>user_r.h</b></a><b>, </b>
+<a href="user_r.c"><b>user_r.c</b></a><b>, </b>
+<a href="../user_eg/user_eg_r.c"><b>user_eg_r.c</b></a><b>, </b>
+<a href="../user_eg2/user_eg2_r.c"><b>user_eg2_r.c</b></a><b>, </b>
+<a href="../user_eg3/user_eg3_r.cpp"><b>user_eg3_r.cpp</b></a><b>, </b>
<dd>User-defined routines. Qhull allows the user to configure
the code with defined constants and specialized routines.
</dd>
</dl>
</blockquote>
</blockquote>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhullr/io_r.c b/src/libqhull_r/io_r.c
similarity index 96%
rename from src/libqhullr/io_r.c
rename to src/libqhull_r/io_r.c
index 53d1ca3..32ce257 100644
--- a/src/libqhullr/io_r.c
+++ b/src/libqhull_r/io_r.c
@@ -1,4062 +1,4062 @@
-/*<html><pre> -<a href="qh-io.htm"
+/*<html><pre> -<a href="qh-io_r.htm"
>-------------------------------</a><a name="TOP">-</a>
io_r.c
Input/Output routines of qhull application
- see qh-io.htm and io_r.h
+ 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/2011/qhull/src/libqhullr/io_r.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/io_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*========= -functions in alphabetical order after qh_produce_output(qh) =====*/
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="produce_output">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="qh_dfacet">-</a>
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;
}
}
} /* qh_dfacet */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="qh_dvertex">-</a>
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;
}
}
} /* qh_dvertex */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="compare_facetarea">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="compare_facetmerge">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="compare_facetvisit">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="compare_vertexpoint">-</a>
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));
}*/
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="copyfilename">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="countfacets">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="detvnorm">-</a>
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(qh, dim, inpoint, normal, &offset);
+ 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(qh, dim, midpoint, normal, &offset);
+ 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(qh, dim, midpoint, normal, &zero); /* qh_detangle uses dim+1 */
+ 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(qh, dim, point, normal, &offset);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="detvridge">-</a>
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, &centers, neighbor);
}else if (firstinf) {
firstinf= False;
qh_setappend(qh, &centers, neighbor);
}
}
}
qsort(SETaddr_(centers, facetT), (size_t)qh_setsize(qh, centers),
sizeof(facetT *), qh_compare_facetvisit);
qh_settempfree(qh, &tricenters);
return centers;
} /* detvridge */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="detvridge3">-</a>
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, &centers, facet);
}else if (firstinf) {
firstinf= False;
qh_setappend(qh, &centers, 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="eachvoronoi">-</a>
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, &centers);
}
}
}
}
}
}
FOREACHneighbor_(atvertex)
neighbor->seen= False;
qh_settempfree(qh, &tricenters);
return totridges;
} /* eachvoronoi */
/*-<a href="qh-poly.htm#TOC"
>-------------------------------</a><a name="eachvoronoi_all">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="facet2point">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="facetvertices">-</a>
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 */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="geomplanes">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="markkeep">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="markvoronoi">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="order_vertexneighbors">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="prepare_output">-</a>
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);
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);
}
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printafacet">-</a>
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(qh, *(normp++), facet->offset, qh->MINdenom_1,
+ *(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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printbegin">-</a>
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, -1);
+ qh_printpointid(qh, qh->fout, NULL, num, point, qh_IDunknown);
FOREACHpoint_(qh->other_points)
- qh_printpointid(qh, qh->fout, NULL, num, point, -1);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printcenter">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printcentrum">-</a>
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(qh, 3, xaxis, normal, yaxis);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printend">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printend4geom">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printextremes">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printextremes_2d">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printextremes_d">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet2geom">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet2geom_points">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet2math">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet3geom_nonsimplicial">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet3geom_points">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet3geom_simplicial">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet3math">-</a>
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, endfmt);
} /* printfacet3math */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet3vertex">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet4geom_nonsimplicial">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacet4geom_simplicial">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacetNvertex_nonsimplicial">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacetNvertex_simplicial">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacetheader">-</a>
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, -1);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacetridges">-</a>
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(qh, ridge, facet, NULL);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printfacets">-</a>
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, -1);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printhyperplaneintersection">-</a>
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(qh, -dist1 + costheta * dist2, denominator,mindenom,&nearzero1);
- t= qh_divzero(qh, -dist2 + costheta * dist1, denominator,mindenom,&nearzero2);
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printline3geom">-</a>
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]);
}
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printneighborhood">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printpoint">-</a>
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=-1)
+ prints 'string p%d'. Skips p%d if id=qh_IDunknown(-1) or qh_IDnone(-3)
notes:
nop if point is NULL
- prints id unless it is undefined (-1)
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 != -1)
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printpoint3">-</a>
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
*/
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printpoints_out">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printpointvect">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printpointvect2">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printridge">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printspheres">-</a>
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
*/
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvdiagram">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvdiagram2">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvertex">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvertexlist">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvertices">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvneighbors">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvoronoi">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvnorm">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printvridge">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="projectdim3">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="readfeasible">-</a>
qh_readfeasible(qh, dim, curline )
read feasible point from current line and qh.fin
returns:
number of lines read from qh.fin
- sets qh.FEASIBLEpoint with malloc'd coordinates
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="readpoints">-</a>
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=
(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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="setfeasible">-</a>
qh_setfeasible(qh, dim )
- set qh.FEASIBLEpoint from qh.feasible_string in "n,n,n" or "n n n" format
+ 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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="skipfacet">-</a>
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 */
-/*-<a href="qh-io.htm#TOC"
+/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="skipfilename">-</a>
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/libqhullr/io_r.h b/src/libqhull_r/io_r.h
similarity index 98%
rename from src/libqhullr/io_r.h
rename to src/libqhull_r/io_r.h
index e3dfe30..4dffca5 100644
--- a/src/libqhullr/io_r.h
+++ b/src/libqhull_r/io_r.h
@@ -1,159 +1,159 @@
/*<html><pre> -<a href="qh-io.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/libqhullr/io_r.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/io_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFio
#define qhDEFio 1
#include "libqhull_r.h"
/*============ constants and flags ==================*/
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_MAXfirst">-</a>
qh_MAXfirst
maximum length of first two lines of stdin
*/
#define qh_MAXfirst 200
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_MINradius">-</a>
qh_MINradius
min radius for Gp and Gv, fraction of maxcoord
*/
#define qh_MINradius 0.02
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_GEOMepsilon">-</a>
qh_GEOMepsilon
adjust outer planes for 'lines closer' and geomview roundoff.
This prevents bleed through.
*/
#define qh_GEOMepsilon 2e-3
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_WHITESPACE">-</a>
qh_WHITESPACE
possible values of white space
*/
#define qh_WHITESPACE " \n\t\v\r\f"
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="RIDGE">-</a>
qh_RIDGE
to select which ridges to print in qh_eachvoronoi
*/
typedef enum
{
qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
}
qh_RIDGE;
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="printvridgeT">-</a>
printvridgeT
prints results of qh_printvdiagram
see:
<a href="io_r.c#printvridge">qh_printvridge</a> for an example
*/
typedef void (*printvridgeT)(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
/*============== -prototypes in alphabetical order =========*/
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);
#endif /* qhDEFio */
diff --git a/src/libqhullr/libqhull_r.c b/src/libqhull_r/libqhull_r.c
similarity index 97%
rename from src/libqhullr/libqhull_r.c
rename to src/libqhull_r/libqhull_r.c
index 44602ea..5c60971 100644
--- a/src/libqhullr/libqhull_r.c
+++ b/src/libqhull_r/libqhull_r.c
@@ -1,1403 +1,1403 @@
-/*<html><pre> -<a href="qh-qhull.htm"
+/*<html><pre> -<a href="qh-qhull_r.htm"
>-------------------------------</a><a name="TOP">-</a>
libqhull_r.c
Quickhull algorithm for convex hulls
qhull() and top-level routines
- see qh-qhull.htm, libqhull.h, unix_r.c
+ 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/2011/qhull/src/libqhullr/libqhull_r.c#9 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/libqhull_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*============= functions in alphabetic order after qhull() =======*/
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="qhull">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="addpoint">-</a>
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) == -1)
+ 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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="build_withrestart">-</a>
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= -1; /* if break from joggle, prevents normal output */
+ 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 != -1 || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
+ 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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="buildhull">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="buildtracing">-</a>
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 != -1 && qh->TRACEdist < REALmax/2) {
+ }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) {
zinc_(Zvisit);
qh->visit_id= 0;
FORALLfacets
facet->visitid= 0;
}
zmax_(Zvvisit2max, (int)qh->vertex_visit/2);
- if (qh->vertex_visit > (unsigned) INT_MAX/2) { /* 31 bits */
+ if (qh->vertex_visit > (unsigned) INT_MAX) {
zinc_(Zvvisit);
qh->vertex_visit= 0;
FORALLvertices
vertex->visitid= 0;
}
qh->furthest_id= furthestid;
qh->RANDOMdist= qh->old_randomdist;
} /* buildtracing */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="errexit2">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="findhorizon">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="nextfurthest">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="partitionall">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="partitioncoplanar">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="partitionpoint">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="partitionvisible">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="precision">-</a>
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 */
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="printsummary">-</a>
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/libqhullr/libqhull_r.h b/src/libqhull_r/libqhull_r.h
similarity index 96%
rename from src/libqhullr/libqhull_r.h
rename to src/libqhull_r/libqhull_r.h
index 1d8187b..a6c5927 100644
--- a/src/libqhullr/libqhull_r.h
+++ b/src/libqhull_r/libqhull_r.h
@@ -1,1090 +1,1107 @@
/*<html><pre> -<a href="qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
libqhull_r.h
user-level header file for using qhull.a library
see qh-qhull.htm, qhull_ra.h
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/libqhull_r.h#10 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/libqhull_r.h#3 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$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 ==============*/
#include "user_r.h" /* user definable constants (e.g., realT) */
#include "mem_r.h"
/* stat_r.h included realT */
#include <setjmp.h>
#include <float.h>
#include <time.h>
#include <stdio.h>
#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 */
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="coordT">-</a>
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
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="pointT">-</a>
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;
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="flagT">-</a>
flagT
Boolean flag as a bit
*/
#define flagT unsigned int
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="boolT">-</a>
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"
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="CENTERtype">-</a>
qh_CENTER
to distinguish facet->center
*/
typedef enum
{
qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum
}
qh_CENTER;
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_PRINT">-</a>
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;
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_ALL">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_ERR">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="qh_FILEstderr">-</a>
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
*/
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
#ifndef DEFqhstatT
#define DEFqhstatT 1
typedef struct qhstatT qhstatT; /* defined in stat_r.h */
#endif
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="facetT">-</a>
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_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; /* centrum for convexity, qh.CENTERtype == qh_AScentrum */
/* Voronoi center, qh.CENTERtype == qh_ASvoronoi */
/* if tricoplanar, shared with a neighbor */
facetT *previous; /* previous facet in the facet_list */
facetT *next; /* next facet in the facet_list */
setT *vertices; /* vertices for this facet, inverse sorted by ID
if simplicial, 1st vertex was apex/furthest */
setT *ridges; /* explicit ridges for nonsimplicial facets.
for simplicial facets, neighbors 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 ->center, ->normal, ->offset, ->maxoutside */
/* all tricoplanars share the same apex */
/* if ->degenerate, does not span facet (one logical ridge) */
/* one tricoplanar has ->keepcentrum and ->coplanarset */
/* during qh_triangulate, f.trivisible points to original facet */
flagT newfacet:1; /* True if facet on qh.newfacet_list (new or merged) */
flagT visible:1; /* True if visible facet (will be deleted) */
flagT toporient:1; /* True if created with top orientation
after merging, use ridge orientation */
flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
flagT seen:1; /* used to perform operations only once, like visitid */
flagT seen2:1; /* used to perform operations only once, like visitid */
flagT flipped:1; /* True if facet is flipped */
flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
flagT notfurthest:1; /* True if last point of outsideset is not furthest*/
/*-------- flags primarily for output ---------*/
flagT good:1; /* True if a facet marked good for output */
flagT isarea:1; /* True if facet->f.area is defined */
/*-------- flags for merging ------------------*/
flagT dupridge:1; /* True if duplicate ridge in facet */
flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
->normal defined (also defined for mergeridge2) */
flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (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) */
};
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="ridgeT">-</a>
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:24; /* unique identifier, =>room for 8 flags, bit field matches qh->ridge_id */
+ 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 */
};
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="vertexT">-</a>
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 visitid:31; /* for use with qh.vertex_visit, size must match */
+ 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 seen2:1; /* another seen flag */
- unsigned id:28; /* unique identifier, bit field matches qh.vertex_id */
- /* =>room for 4 flags */
flagT seen:1; /* used to perform operations only once */
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 ============================*/
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh">-</a>
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.
*/
+#define QHULL_LIB_CHECK qh_lib_check(2, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(2, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
+
struct qhT {
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-const">-</a>
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 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 normals (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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-prec">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-codetern">-</a>
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) */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-lists">-</a>
qh facet and vertex lists
defines lists of facets, new facets, visible facets, vertices, and
new vertices. Includes counts, next ids, and trace ids.
see:
qh_resetlists()
*/
facetT *facet_list; /* first facet */
facetT *facet_tail; /* end of facet_list (dummy facet) */
facetT *facet_next; /* next facet for buildhull()
previous facets do not have outside sets
NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
facetT *newfacet_list; /* list of new facets to end of facet_list */
facetT *visible_list; /* list of visible facets preceeding newfacet_list,
facet->visible set */
int num_visible; /* current number of visible facets */
unsigned tracefacet_id; /* set at init, then can print whenever */
facetT *tracefacet; /* set in newfacet/mergefacet, undone in delfacet*/
unsigned tracevertex_id; /* set at buildtracing, can print whenever */
vertexT *tracevertex; /* set in newvertex, undone in delvertex*/
vertexT *vertex_list; /* list of all vertices, to vertex_tail */
vertexT *vertex_tail; /* end of vertex_list (dummy vertex) */
vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
all vertices have 'newlist' set */
int num_facets; /* number of facets in facet_list
includes visble faces (num_visible) */
int num_vertices; /* number of vertices in facet_list */
int num_outside; /* number of points in outsidesets (for tracing and RANDOMoutside)
includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
int num_good; /* number of good facets (after findgood_all) */
unsigned facet_id; /* ID of next, new facet from newfacet() */
- unsigned ridge_id:24; /* ID of next, new ridge from newridge() */
- unsigned vertex_id:24; /* ID of next, new vertex from newvertex() */
+ unsigned ridge_id; /* ID of next, new ridge from newridge() */
+ unsigned vertex_id; /* ID of next, new vertex from newvertex() */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-var">-</a>
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 */
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:31; /* unique ID for searching vertices, reset with qh_buildtracing */
+ 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) */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-set">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-buf">-</a>
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 */
/*-<a href="qh-globa_r.htm#TOC"
>--------------------------------</a><a name="qh-static">-</a>
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) */
/*-<a href="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh-const">-</a>
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, for qh_rboxpoints only */
+ 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- =========================*/
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="otherfacet_">-</a>
otherfacet_(ridge, facet)
return neighboring facet for a ridge in facet
*/
#define otherfacet_(ridge, facet) \
(((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="getid_">-</a>
getid_(p)
return int ID for facet, ridge, or vertex
- return -1 if NULL
+ return qh_IDunknown(-1) if NULL
*/
-#define getid_(p) ((p) ? (int)((p)->id) : -1)
+#define getid_(p) ((p) ? (int)((p)->id) : qh_IDunknown)
/*============== FORALL macros ===================*/
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLfacets">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLpoints">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLpoint_">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLvertices">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHfacet_">-</a>
FOREACHfacet_( facets ) { ... }
assign 'facet' to each facet in facets
declare:
facetT *facet, **facetp;
see:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHneighbor_">-</a>
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:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHneighbor_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighbor)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHpoint_">-</a>
FOREACHpoint_( points ) { ... }
assign 'point' to each point in points set
declare:
pointT *point, **pointp;
see:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHpoint_(points) FOREACHsetelement_(pointT, points, point)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHridge_">-</a>
FOREACHridge_( ridges ) { ... }
assign 'ridge' to each ridge in ridges set
declare:
ridgeT *ridge, **ridgep;
see:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHridge_(ridges) FOREACHsetelement_(ridgeT, ridges, ridge)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertex_">-</a>
FOREACHvertex_( vertices ) { ... }
assign 'vertex' to each vertex in vertices set
declare:
vertexT *vertex, **vertexp;
see:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHfacet_i_">-</a>
FOREACHfacet_i_( qh, facets ) { ... }
assign 'facet' and 'facet_i' for each facet in facets set
declare:
facetT *facet;
int facet_n, facet_i;
see:
<a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHfacet_i_(qh, facets) FOREACHsetelement_i_(qh, facetT, facets, facet)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHneighbor_i_">-</a>
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:
<a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHneighbor_i_(qh, facet) FOREACHsetelement_i_(qh, facetT, facet->neighbors, neighbor)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHpoint_i_">-</a>
FOREACHpoint_i_( qh, points ) { ... }
assign 'point' and 'point_i' for each point in points set
declare:
pointT *point;
int point_n, point_i;
see:
<a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHpoint_i_(qh, points) FOREACHsetelement_i_(qh, pointT, points, point)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHridge_i_">-</a>
FOREACHridge_i_( qh, ridges ) { ... }
assign 'ridge' and 'ridge_i' for each ridge in ridges set
declare:
ridgeT *ridge;
int ridge_n, ridge_i;
see:
<a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHridge_i_(qh, ridges) FOREACHsetelement_i_(qh, ridgeT, ridges, ridge)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertex_i_">-</a>
FOREACHvertex_i_( qh, vertices ) { ... }
assign 'vertex' and 'vertex_i' for each vertex in vertices set
declare:
vertexT *vertex;
int vertex_n, vertex_i;
see:
<a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
*/
#define FOREACHvertex_i_(qh, vertices) FOREACHsetelement_i_(qh, vertexT, vertices,vertex)
/********* -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_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 isQHpointer, 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);
#endif /* qhDEFlibqhull */
diff --git a/src/libqhull_r/libqhull_r.pro b/src/libqhull_r/libqhull_r.pro
new file mode 100644
index 0000000..3ddd87e
--- /dev/null
+++ b/src/libqhull_r/libqhull_r.pro
@@ -0,0 +1,56 @@
+# -------------------------------------------------
+# 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
diff --git a/src/libqhullr/mem_r.c b/src/libqhull_r/mem_r.c
similarity index 88%
rename from src/libqhullr/mem_r.c
rename to src/libqhull_r/mem_r.c
index 3419061..c6b4b79 100644
--- a/src/libqhullr/mem_r.c
+++ b/src/libqhull_r/mem_r.c
@@ -1,530 +1,556 @@
-/*<html><pre> -<a href="qh-mem.htm"
+/*<html><pre> -<a href="qh-mem_r.htm"
>-------------------------------</a><a name="TOP">-</a>
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.htm and mem_r.h
+ 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/2011/qhull/src/libqhullr/mem_r.c#8 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/mem_r.c#3 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "mem_r.h"
#include "libqhull_r.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef qh_NOmem
/*============= internal functions ==============*/
static int qh_intcompare(const void *i, const void *j);
/*========== functions in alphabetical order ======== */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="intcompare">-</a>
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memalloc">-</a>
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'
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 */
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="memcheck">-</a>
+
+ qh_memcheck(qh)
+*/
+void qh_memcheck(qhT *qh) {
+ int i, count, totfree= 0;
+ void *object;
+
+ if (!qh) {
+ fprintf(stderr, "QH6243 qh_memcheck(qh): 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(qh, stderr, 6244, "qh_memcheck: 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 */
+
+/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memfree">-</a>
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;
qh_free(object);
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);
}
} /* memfree */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memfreeshort">-</a>
qh_memfreeshort(qh, curlong, totlong )
frees up all short and qhmem memory allocations
returns:
number and size of current long allocations
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="meminit">-</a>
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="meminitbuffers">-</a>
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memsetup">-</a>
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memsize">-</a>
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memstatistics">-</a>
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, count, totfree= 0;
+ int i;
+ int count;
void *object;
- 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, "qh_memstatistics internal error: totfree %d not equal to freelist total %d\n", qh->qhmem.totfree, totfree);
- qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
- }
+ 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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
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 */
-/*-<a href="qh-mem.htm#TOC"
+/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memtotlong">-</a>
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/libqhullr/mem_r.h b/src/libqhull_r/mem_r.h
similarity index 96%
rename from src/libqhullr/mem_r.h
rename to src/libqhull_r/mem_r.h
index e6aff30..c811560 100644
--- a/src/libqhullr/mem_r.h
+++ b/src/libqhull_r/mem_r.h
@@ -1,223 +1,226 @@
/*<html><pre> -<a href="qh-mem.htm"
>-------------------------------</a><a name="TOP">-</a>
mem_r.h
prototypes for memory management functions
see qh-mem.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/2011/qhull/src/libqhullr/mem_r.h#5 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/mem_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFmem
#define qhDEFmem 1
#include <stdio.h>
#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
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
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
*/
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="TRACEshort">-</a>
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 <a href="user.h#MEMalign">qh_MEMalign</a> 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 */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="ptr_intT">-</a>
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.
+ This matches Qt convention and is easier to work with.
*/
-#if _MSC_VER && defined(_WIN64)
+#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
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="qhmemT">-</a>
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 ====================*/
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memalloc_">-</a>
qh_memalloc_(qh, freelistp, insize, 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
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memfree_">-</a>
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 ============*/
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);
#endif /* qhDEFmem */
diff --git a/src/libqhullr/merge_r.c b/src/libqhull_r/merge_r.c
similarity index 96%
rename from src/libqhullr/merge_r.c
rename to src/libqhull_r/merge_r.c
index 1e1d39d..66ed545 100644
--- a/src/libqhullr/merge_r.c
+++ b/src/libqhull_r/merge_r.c
@@ -1,3623 +1,3623 @@
-/*<html><pre> -<a href="qh-merge.htm#TOC"
+/*<html><pre> -<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
merge_r.c
merges non-convex facets
- see qh-merge.htm and merge_r.h
+ 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/2011/qhull/src/libqhullr/merge_r.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/merge_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
#ifndef qh_NOmerge
/*===== functions(alphabetical after premerge and postmerge) ======*/
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="premerge">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="postmerge">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="all_merges">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="appendmergeset">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="basevertices">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="checkconnect">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="checkzero">-</a>
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) {
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="compareangle">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="comparemerge">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="comparevisit">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="copynonconvex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="degen_redundant_facet">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="degen_redundant_neighbors">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="find_newvertex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="findbest_test">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="findbestneighbor">-</a>
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:
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);
*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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="flippedmerges">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="forcedmerges">-</a>
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
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;
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);
}
if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
dist1= qh_getdistance(qh, facet1, facet2, &mindist1, &maxdist1);
dist2= qh_getdistance(qh, facet2, facet1, &mindist2, &maxdist2);
trace0((qh, qh->ferr, 16, "qh_forcedmerges: duplicate ridge between f%d and f%d, dist %2.2g and reverse dist %2.2g during p%d\n",
facet1->id, facet2->id, dist1, dist2, qh->furthest_id));
if (dist1 < dist2)
qh_mergefacet(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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="getmergeset">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="getmergeset_initial">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="hashridge">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="hashridge_find">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="makeridges">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mark_dupridges">-</a>
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
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="maydropneighbor">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="merge_degenredundant">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="merge_nonconvex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergecycle">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergecycle_all">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergecycle_facets">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergecycle_neighbors">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergecycle_ridges">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergecycle_vneighbors">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergefacet">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergefacet2d">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergeneighbors">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergeridges">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergesimplex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergevertex_del">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergevertex_neighbors">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="mergevertices">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="neighbor_intersections">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="newvertices">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="reducevertices">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="redundant_vertex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="remove_extravertices">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="rename_sharedvertex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="renameridgevertex">-</a>
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);
qh_delridge(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));
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="renamevertex">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="test_appendmerge">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="test_vneighbors">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="tracemerge">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="tracemerging">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="updatetested">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="vertexridges">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="vertexridges_facet">-</a>
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 */
-/*-<a href="qh-merge.htm#TOC"
+/*-<a href="qh-merge_r.htm#TOC"
>-------------------------------</a><a name="willdelete">-</a>
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/libqhullr/merge_r.h b/src/libqhull_r/merge_r.h
similarity index 98%
rename from src/libqhullr/merge_r.h
rename to src/libqhull_r/merge_r.h
index 4d71d34..fab7fc1 100644
--- a/src/libqhullr/merge_r.h
+++ b/src/libqhull_r/merge_r.h
@@ -1,178 +1,178 @@
/*<html><pre> -<a href="qh-merge.htm"
>-------------------------------</a><a name="TOP">-</a>
merge_r.h
header file for merge_r.c
see qh-merge.htm and merge_r.c
Copyright (c) 1993-2015 C.B. Barber.
- $Id: //main/2011/qhull/src/libqhullr/merge_r.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/merge_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFmerge
#define qhDEFmerge 1
#include "libqhull_r.h"
/*============ -constants- ==============*/
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEredundant">-</a>
qh_ANGLEredundant
indicates redundant merge in mergeT->angle
*/
#define qh_ANGLEredundant 6.0
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEdegen">-</a>
qh_ANGLEdegen
indicates degenerate facet in mergeT->angle
*/
#define qh_ANGLEdegen 5.0
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEconcave">-</a>
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
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="MRG">-</a>
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;
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_MERGEapex">-</a>
qh_MERGEapex
flag for qh_mergefacet() to indicate an apex merge
*/
#define qh_MERGEapex True
/*============ -structures- ====================*/
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="mergeT">-</a>
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- =========================*/
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="FOREACHmerge_">-</a>
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 <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
/*============ prototypes in alphabetical order after pre/postmerge =======*/
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);
#endif /* qhDEFmerge */
diff --git a/src/libqhullr/poly2_r.c b/src/libqhull_r/poly2_r.c
similarity index 95%
rename from src/libqhullr/poly2_r.c
rename to src/libqhull_r/poly2_r.c
index 1e99af7..489ff7e 100644
--- a/src/libqhullr/poly2_r.c
+++ b/src/libqhull_r/poly2_r.c
@@ -1,3153 +1,3152 @@
-/*<html><pre> -<a href="qh-poly.htm"
+/*<html><pre> -<a href="qh-poly_r.htm"
>-------------------------------</a><a name="TOP">-</a>
poly2_r.c
implements polygons and simplicies
- see qh-poly.htm, poly_r.h and libqhull_r.h
+ 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/2011/qhull/src/libqhullr/poly2_r.c#8 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/poly2_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*======== functions in alphabetical order ==========*/
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="addhash">-</a>
- qh_addhash(qh, newelem, hashtable, hashsize, hash )
+ qh_addhash( newelem, hashtable, hashsize, hash )
add newelem to linear hash table at hash if not already there
*/
-void qh_addhash(qhT *qh, void *newelem, setT *hashtable, int hashsize, int hash) {
+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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="check_bestdist">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="check_maxout">-</a>
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->id);
}
}
}while
(maxoutside > 2*old_maxoutside);
/* if qh.maxoutside increases substantially, qh_SEARCHdist is not valid
e.g., RBOX 5000 s Z1 G1e-13 t1001200614 | qhull */
zzadd_(Zcheckpart, numpart);
qh_settempfree(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
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="check_output">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="check_point">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="check_points">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="checkconvex">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="checkfacet">-</a>
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 (!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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="checkflipped_all">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="checkpolygon">-</a>
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) == -1) {
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="checkvertex">-</a>
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) == -1) {
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="clearcenters">-</a>
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;
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="createsimplex">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="delridge">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="delvertex">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="facet3vertex">-</a>
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(qh, ridge, facet, &vertex))) {
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="findbestfacet">-</a>
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 <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
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:
<a href="geom_r.c#findbest">qh_findbest</a>
*/
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 && bestoutside)
|| (!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, totpart));
return bestfacet;
} /* findbestfacet */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="findbestlower">-</a>
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;
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) {
qh_fprintf(qh, qh->ferr, 6228, "\n\
Qhull internal error (qh_findbestlower): all neighbors of facet %d are flipped or upper Delaunay.\n\
Please report this error to qhull_bug@qhull.org with the input and all of the output.\n",
upperfacet->id);
qh_errexit(qh, qh_ERRqhull, upperfacet, NULL);
}
*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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="findfacet_all">-</a>
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:
for library users, not 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="findgood">-</a>
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, qh->GOODvertexp, facet->vertices)) {
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="findgood_all">-</a>
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, qh->GOODvertexp, facet->vertices))) {
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="furthestnext">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="furthestout">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="infiniteloop">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="initbuild">-</a>
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= -1;
+ 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, qh->GOODvertexp, vertices)) {
+ && !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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="initialhull">-</a>
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 input error: Can not compute the upper Delaunay triangulation or upper Voronoi diagram of cocircular/cospherical points.\n");
else
qh_fprintf(qh, qh->ferr, 6239, "Qhull input error: Use option 'Qz' for the Delaunay triangulation or Voronoi diagram of cocircular/cospherical points. Option 'Qz' adds a point \"at infinity\" (above the corresponding paraboloid).\n");
qh_errexit(qh, qh_ERRinput, NULL, NULL);
}
qh_precision(qh, "initial facet is coplanar with interior point");
qh_fprintf(qh, qh->ferr, 6154, "qhull precision error: initial facet %d is coplanar with the interior point\n",
facet->id);
qh_errexit(qh, qh_ERRsingular, facet, NULL);
}
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="initialvertices">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="isvertex">-</a>
- qh_isvertex(qh, )
+ qh_isvertex( point, vertices )
returns vertex if point is in vertex set, else returns NULL
notes:
for qh.GOODvertex
*/
-vertexT *qh_isvertex(qhT *qh, pointT *point, setT *vertices) {
+vertexT *qh_isvertex(pointT *point, setT *vertices) {
vertexT *vertex, **vertexp;
FOREACHvertex_(vertices) {
if (vertex->point == point)
return vertex;
}
return NULL;
} /* isvertex */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="makenewfacets">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="matchduplicates">-</a>
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;
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="nearcoplanar">-</a>
qh_nearcoplanar()
for all facets, remove near-inside points from facet->coplanarset</li>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="nearvertex">-</a>
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(qh, vertex->point, point, -dim);
+ dist= qh_pointdist(vertex->point, point, -dim);
if (dist < bestdist) {
bestdist= dist;
bestvertex= vertex;
}
}
if (facet->tricoplanar)
qh_settempfree(qh, &vertices);
*bestdistp= sqrt(bestdist);
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)));
return bestvertex;
} /* nearvertex */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="newhashtable">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="newvertex">-</a>
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 == 0xFFFFFF) {
- qh_fprintf(qh, qh->ferr, 6159, "qhull error: more than %d vertices. ID field overflows and two vertices\n\
-may have the same identifier. Vertices will not be sorted correctly.\n", 0xFFFFFF);
+ if (qh->vertex_id == 0xFFFFFFFF) {
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="nextridge3d">-</a>
- qh_nextridge3d(qh, atridge, facet, vertex )
+ 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(qhT *qh, ridgeT *atridge, facetT *facet, vertexT **vertexp) {
+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(qhT *qh, ridgeT *atridge, facetT *facet, vertexT **vertexp) {
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) {
return NULL;
}
#endif /* qh_NOmerge */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="outcoplanar">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="point">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="point_add">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="pointfacet">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="pointvertex">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="prependfacet">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="printhashtable">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="printlists">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="resetlists">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="setvoronoi_all">-</a>
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
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="triangulate">-</a>
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) {
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 */
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="triangulate_facet">-</a>
qh_triangulate_facet(qh, facetA)
triangulate a non-simplicial facet
if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center
returns:
qh.newfacet_list == simplicial facets
facet->tricoplanar set and ->keepcentrum false
facet->degenerate set if duplicated apex
facet->f.trivisible set to facetA
facet->center copied from facetA (created if qh_ASvoronoi)
qh_eachvoronoi, qh_detvridge, qh_detvridge3 assume centers copied
facet->normal,offset,maxoutside copied from facetA
notes:
qh_makenew_nonsimplicial uses neighbor->seen for the same
see also:
qh_addpoint() -- add a point
qh_makenewfacets() -- construct a cone of facets for a new vertex
design:
if qh_ASvoronoi,
compute Voronoi center (facet->center)
select first vertex (highest ID to preserve ID ordering of ->vertices)
triangulate from vertex to ridges
copy facet->center, normal, offset
update vertex neighbors
*/
void qh_triangulate_facet(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) {
newfacet->keepcentrum= True;
newfacet->normal= qh_copypoints(qh, facetA->normal, 1, qh->hull_dim);
if (qh->CENTERtype == qh_AScentrum)
newfacet->center= qh_getcentrum(qh, newfacet);
else
newfacet->center= qh_copypoints(qh, facetA->center, 1, qh->hull_dim);
}else {
newfacet->keepcentrum= False;
newfacet->normal= facetA->normal;
newfacet->center= facetA->center;
}
newfacet->offset= facetA->offset;
#if qh_MAXoutside
newfacet->maxoutside= facetA->maxoutside;
#endif
}
qh_matchnewfacets(qh /*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, empty visible_list and newvertex_list*/);
qh_resetlists(qh, False, !qh_RESETvisible /*qh.newfacet_list, empty visible_list and newvertex_list*/);
} /* triangulate_facet */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="triangulate_link">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="triangulate_mirror">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="triangulate_null">-</a>
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 */
- /*-<a href="qh-poly.htm#TOC"
+ /*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="vertexintersect">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="vertexintersect_new">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="vertexneighbors">-</a>
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: determing neighboring facets for each vertex\n"));
qh->vertex_visit++;
FORALLfacets {
if (facet->visible)
continue;
FOREACHvertex_(facet->vertices) {
if (vertex->visitid != qh->vertex_visit) {
vertex->visitid= qh->vertex_visit;
vertex->neighbors= qh_setnew(qh, qh->hull_dim);
}
qh_setappend(qh, &vertex->neighbors, facet);
}
}
qh->VERTEXneighbors= True;
} /* vertexneighbors */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="vertexsubset">-</a>
- qh_vertexsubset(qh, vertexsetA, vertexsetB )
+ 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(qhT *qh, setT *vertexsetA, setT *vertexsetB) {
+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/libqhullr/poly_r.c b/src/libqhull_r/poly_r.c
similarity index 94%
rename from src/libqhullr/poly_r.c
rename to src/libqhull_r/poly_r.c
index bb2cc36..6b662cc 100644
--- a/src/libqhullr/poly_r.c
+++ b/src/libqhull_r/poly_r.c
@@ -1,1199 +1,1199 @@
-/*<html><pre> -<a href="qh-poly.htm"
+/*<html><pre> -<a href="qh-poly_r.htm"
>-------------------------------</a><a name="TOP">-</a>
poly_r.c
implements polygons and simplices
- see qh-poly.htm, poly_r.h and libqhull_r.h
+ 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/2011/qhull/src/libqhullr/poly_r.c#8 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/poly_r.c#3 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*======== functions in alphabetical order ==========*/
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="appendfacet">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="appendvertex">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="attachnewfacets">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="checkflipped">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="delfacet">-</a>
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 !qh_NOmem */
+ 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) { /* uses 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="deletevisible">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="facetintersect">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="gethash">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="makenewfacet">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="makenewplanes">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="makenew_nonsimplicial">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="makenew_simplicial">-</a>
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, visibleskip;
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="matchneighbor">-</a>
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(qh, newfacet, qh->hash_table, hashsize, hash);
+ 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);
SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge;
matchfacet->dupridge= True;
if (!matchfacet->normal)
qh_setfacetplane(qh, matchfacet);
- qh_addhash(qh, matchfacet, qh->hash_table, hashsize, hash);
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="matchnewfacets">-</a>
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; newskip<qh->hull_dim; newskip++) /* furthest/horizon already matched */
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="matchvertices">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="newfacet">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="newridge">-</a>
qh_newridge()
return a new ridge
*/
ridgeT *qh_newridge(qhT *qh) {
ridgeT *ridge;
- void **freelistp; /* used !qh_NOmem */
+ 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 == 0xFFFFFF) {
+ if (qh->ridge_id == 0xFFFFFFFF) {
qh_fprintf(qh, qh->ferr, 7074, "\
-qhull warning: more than %d ridges. ID field overflows and two ridges\n\
-may have the same identifier. Otherwise output ok.\n", 0xFFFFFF);
+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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="pointid">-</a>
- qh_pointid(qh, )
+ qh_pointid(qh, point)
return id for a point,
- returns -3 if null, -2 if interior, or -1 if not known
+ returns qh_IDnone(-3) if null, qh_IDinterior(-2) if interior, or qh_IDunknown(-1) if not known
- alternative code:
+ 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 -3;
+ return qh_IDnone;
else if (point == qh->interior_point)
- return -2;
+ 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 -1;
+ return qh_IDunknown;
return (int)id;
} /* pointid */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="removefacet">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="removevertex">-</a>
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 */
-/*-<a href="qh-poly.htm#TOC"
+/*-<a href="qh-poly_r.htm#TOC"
>-------------------------------</a><a name="updatevertices">-</a>
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/libqhullr/poly_r.h b/src/libqhull_r/poly_r.h
similarity index 96%
rename from src/libqhullr/poly_r.h
rename to src/libqhull_r/poly_r.h
index 3ab3b4e..c9b697d 100644
--- a/src/libqhullr/poly_r.h
+++ b/src/libqhull_r/poly_r.h
@@ -1,295 +1,295 @@
/*<html><pre> -<a href="qh-poly.htm"
>-------------------------------</a><a name="TOP">-</a>
poly_r.h
header file for poly_r.c and poly2_r.c
see qh-poly.htm, libqhull_r.h and poly_r.c
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/poly_r.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/poly_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFpoly
#define qhDEFpoly 1
#include "libqhull_r.h"
/*=============== constants ========================== */
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="ALGORITHMfault">-</a>
ALGORITHMfault
use as argument to checkconvex() to report errors during buildhull
*/
#define qh_ALGORITHMfault 0
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="DATAfault">-</a>
DATAfault
use as argument to checkconvex() to report errors during initialhull
*/
#define qh_DATAfault 1
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="DUPLICATEridge">-</a>
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
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="MERGEridge">-</a>
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- =========================*/
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLfacet_">-</a>
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 )
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLnew_facets">-</a>
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 )
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLvertex_">-</a>
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 )
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLvisible_facets">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLsame_">-</a>
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)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLsame_cycle_">-</a>
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))
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHneighborA_">-</a>
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:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHneighborA_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighborA)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvisible_">-</a>
FOREACHvisible_( facets ) { ... }
assign 'visible' to each facet in facets
notes:
uses 'facetT *facet, *facetp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHnewfacet_">-</a>
FOREACHnewfacet_( facets ) { ... }
assign 'newfacet' to each facet in facets
notes:
uses 'facetT *newfacet, *newfacetp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertexA_">-</a>
FOREACHvertexA_( vertices ) { ... }
assign 'vertexA' to each vertex in vertices
notes:
uses 'vertexT *vertexA, *vertexAp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertexreverse12_">-</a>
FOREACHvertexreverse12_( vertices ) { ... }
assign 'vertex' to each vertex in vertices
reverse order of first two vertices
notes:
uses 'vertexT *vertex, *vertexp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
/*=============== prototypes poly_r.c in alphabetical order ================*/
void qh_appendfacet(qhT *qh, facetT *facet);
void qh_appendvertex(qhT *qh, vertexT *vertex);
void qh_attachnewfacets(qhT *qh /* qh.visible_list, 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(qhT *qh, void *newelem, setT *hashtable, int hashsize, int hash);
+void qh_addhash(void *newelem, setT *hashtable, int hashsize, int hash);
void qh_check_bestdist(qhT *qh);
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(qhT *qh, pointT *point, setT *vertices);
+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(qhT *qh, ridgeT *atridge, facetT *facet, vertexT **vertexp);
+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 newfacet_list 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(qhT *qh, setT *vertexsetA, setT *vertexsetB);
+boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
#endif /* qhDEFpoly */
diff --git a/src/libqhull_r/qh-geom_r.htm b/src/libqhull_r/qh-geom_r.htm
new file mode 100644
index 0000000..43b8b39
--- /dev/null
+++ b/src/libqhull_r/qh-geom_r.htm
@@ -0,0 +1,293 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>geom_r.c, geom2_r.c -- geometric and floating point routines</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm#TOC">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+
+<hr>
+<!-- Main text of document. -->
+
+<h2>geom_r.c, geom2_r.c, random_r.c -- geometric and floating point routines</h2>
+<blockquote>
+<p>Geometrically, a vertex is a point with <em>d</em> coordinates
+and a facet is a halfspace. A <em>halfspace</em> is defined by an
+oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
+is defined by <em>d</em> normalized coefficients and an offset. A
+point is <em>above</em> a facet if its distance to the facet is
+positive.</p>
+
+<p>Qhull uses floating point coordinates for input points,
+vertices, halfspace equations, centrums, and an interior point.</p>
+
+<p>Qhull may be configured for single precision or double
+precision floating point arithmetic (see <a href="user_r.h#realT">realT</a>
+). </p>
+
+<p>Each floating point operation may incur round-off error (see
+<a href="qh-merge_r.htm#TOC">Merge</a>). 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. </p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <b>Geom</b>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
+<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a> &#149;
+<a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a> &#149;
+<a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="geom_r.c">geom_r.c</a>,
+<a href="geom2_r.c">geom2_r.c</a>, <a href="geom_r.h">geom_r.h</a>,
+<a href="random_r.c">random_r.c</a>, <a href="random_r.h">random_r.h</a>
+</h3>
+
+<ul>
+<li><a href="#gtype">geometric data types and constants</a> </li>
+<li><a href="#gmacro">mathematical macros</a>
+</li>
+<li><a href="#gmath">mathematical functions</a> </li>
+<li><a href="#gcomp">computational geometry functions</a> </li>
+<li><a href="#gpoint">point array functions</a> </li>
+<li><a href="#gfacet">geometric facet functions</a> </li>
+<li><a href="#ground">geometric roundoff functions</a></li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gtype">geometric data types
+and constants</a></h3>
+
+<ul>
+<li><a href="libqhull_r.h#coordT">coordT</a> coordinates and
+coefficients are stored as realT</li>
+<li><a href="libqhull_r.h#pointT">pointT</a> a point is an array
+of <tt>DIM3</tt> coordinates </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gmacro">mathematical macros</a></h3>
+
+<ul>
+<li><a href="geom_r.h#fabs_">fabs_</a> returns the absolute
+value of a </li>
+<li><a href="geom_r.h#fmax_">fmax_</a> returns the maximum
+value of a and b </li>
+<li><a href="geom_r.h#fmin_">fmin_</a> returns the minimum
+value of a and b </li>
+<li><a href="geom_r.h#maximize_">maximize_</a> maximize a value
+</li>
+<li><a href="geom_r.h#minimize_">minimize_</a> minimize a value
+</li>
+<li><a href="geom_r.h#det2_">det2_</a> compute a 2-d
+determinate </li>
+<li><a href="geom_r.h#det3_">det3_</a> compute a 3-d
+determinate </li>
+<li><a href="geom_r.h#dX">dX, dY, dZ</a> compute the difference
+between two coordinates </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gmath">mathematical functions</a></h3>
+
+<ul>
+<li><a href="geom_r.c#backnormal">qh_backnormal</a> solve for
+normal using back substitution </li>
+<li><a href="geom2_r.c#crossproduct">qh_crossproduct</a>
+compute the cross product of two 3-d vectors </li>
+<li><a href="geom2_r.c#determinant">qh_determinant</a> compute
+the determinant of a square matrix </li>
+<li><a href="geom_r.c#gausselim">qh_gausselim</a> Gaussian
+elimination with partial pivoting </li>
+<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
+implements Gram-Schmidt orthogonalization by rows </li>
+<li><a href="geom2_r.c#maxabsval">qh_maxabsval</a> return max
+absolute value of a vector </li>
+<li><a href="geom2_r.c#minabsval">qh_minabsval</a> return min
+absolute value of a dim vector </li>
+<li><a href="geom2_r.c#mindiff">qh_mindiff</a> return index of
+min absolute difference of two vectors </li>
+<li><a href="geom_r.c#normalize">qh_normalize</a> normalize a
+vector </li>
+<li><a href="geom_r.c#normalize2">qh_normalize2</a> normalize a
+vector and report if too small </li>
+<li><a href="geom2_r.c#printmatrix">qh_printmatrix</a> print
+matrix given by row vectors </li>
+<li><a href="random_r.c#rand">qh_rand/srand</a> generate random
+numbers </li>
+<li><a href="random_r.c#randomfactor">qh_randomfactor</a> return
+a random factor near 1.0 </li>
+<li><a href="random_r.c#randommatrix">qh_randommatrix</a>
+generate a random dimXdim matrix in range (-1,1) </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gcomp">computational geometry functions</a></h3>
+
+<ul>
+<li><a href="geom2_r.c#detsimplex">qh_detsimplex</a> compute
+determinate of a simplex of points </li>
+<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
+<li><a href="geom2_r.c#distnorm">qh_distnorm</a> compute
+distance from point to hyperplane as defined by normal and offset</li>
+<li><a href="geom2_r.c#facetarea_simplex">qh_facetarea_simplex</a>
+return area of a simplex</li>
+<li><a href="geom_r.c#getangle">qh_getangle</a> return cosine
+of angle (i.e., dot product) </li>
+<li><a href="geom_r.c#getcenter">qh_getcenter</a> return
+arithmetic center for a set of vertices </li>
+<li><a href="geom2_r.c#pointdist">qh_pointdist</a> return
+distance between two points </li>
+<li><a href="geom2_r.c#rotatepoints">qh_rotatepoints</a> rotate
+numpoints points by a row matrix </li>
+<li><a href="geom2_r.c#sethalfspace">qh_sethalfspace</a> set
+coords to dual of halfspace relative to an interior point </li>
+<li><a href="geom_r.c#sethyperplane_det">qh_sethyperplane_det</a>
+return hyperplane for oriented simplex using determinates
+</li>
+<li><a href="geom_r.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
+return hyperplane for oriented simplex using Gaussian
+elimination </li>
+<li><a href="geom2_r.c#voronoi_center">qh_voronoi_center</a>
+return Voronoi center for a set of points </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gpoint">point array functions</a></h3>
+<ul>
+<li><a href="geom2_r.c#copypoints">qh_copypoints</a> return
+malloc'd copy of points</li>
+<li><a href="geom2_r.c#joggleinput">qh_joggleinput</a> joggle
+input points by qh.JOGGLEmax </li>
+<li><a href="geom2_r.c#maxmin">qh_maxmin</a> return max/min
+points for each dimension</li>
+<li><a href="geom2_r.c#maxsimplex">qh_maxsimplex</a> determines
+maximum simplex for a set of points </li>
+<li><a href="geom2_r.c#printpoints">qh_printpoints</a> print ids for a
+set of points </li>
+<li><a href="geom2_r.c#projectinput">qh_projectinput</a> project
+input using qh DELAUNAY and qh low_bound/high_bound </li>
+<li><a href="geom2_r.c#projectpoints">qh_projectpoints</a>
+project points along one or more dimensions </li>
+<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
+input points using row matrix </li>
+<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
+input points using qh low_bound/high_bound </li>
+<li><a href="geom2_r.c#scalelast">qh_scalelast</a> scale last
+coordinate to [0,m] for Delaunay triangulations </li>
+<li><a href="geom2_r.c#scalepoints">qh_scalepoints</a> scale
+points to new lowbound and highbound </li>
+<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
+points to paraboloid for Delaunay triangulation </li>
+<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
+generate dual for halfspace intersection with interior
+point </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gfacet">geometric facet functions</a></h3>
+<ul>
+<li><a href="geom_r.c#distplane">qh_distplane</a> return
+distance from point to facet </li>
+<li><a href="geom2_r.c#facetarea">qh_facetarea</a> return area
+of a facet </li>
+<li><a href="geom2_r.c#facetcenter">qh_facetcenter</a> return
+Voronoi center for a facet's vertices </li>
+<li><a href="geom_r.c#findbest">qh_findbest</a> find visible
+facet or best facet for a point </li>
+<li><a href="geom_r.c#findbesthorizon">qh_findbesthorizon</a>
+update best new facet with horizon facets</li>
+<li><a href="geom_r.c#findbestnew">qh_findbestnew</a> find best
+new facet for point </li>
+<li><a href="geom2_r.c#getarea">qh_getarea</a> get area of all
+facets in facetlist, collect statistics </li>
+<li><a href="geom_r.c#getcentrum">qh_getcentrum</a> return
+centrum for a facet </li>
+<li><a href="geom_r.c#getdistance">qh_getdistance</a> returns
+the max and min distance of a facet's vertices to a
+neighboring facet</li>
+<li><a href="geom2_r.c#findgooddist">qh_findgooddist</a> find
+best good facet visible for point from facet </li>
+<li><a href="geom2_r.c#inthresholds">qh_inthresholds</a> return
+True if facet normal within 'Pdn' and 'PDn'</li>
+<li><a href="geom2_r.c#orientoutside">qh_orientoutside</a>
+orient facet so that <tt>qh.interior_point</tt> is inside</li>
+<li><a href="geom_r.c#projectpoint">qh_projectpoint</a> project
+point onto a facet </li>
+<li><a href="geom_r.c#setfacetplane">qh_setfacetplane</a> sets
+the hyperplane for a facet </li>
+<li><a href="geom2_r.c#sharpnewfacets">qh_sharpnewfacets</a> true
+if new facets contains a sharp corner</li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="ground">geometric roundoff functions</a></h3>
+<ul>
+<li><a href="geom2_r.c#detjoggle">qh_detjoggle</a> determine
+default joggle for points and distance roundoff error</li>
+<li><a href="geom2_r.c#detroundoff">qh_detroundoff</a>
+determine maximum roundoff error and other precision constants</li>
+<li><a href="geom2_r.c#distround">qh_distround</a> compute
+maximum roundoff error due to a distance computation to a
+normalized hyperplane</li>
+<li><a href="geom2_r.c#divzero">qh_divzero</a> divide by a
+number that is nearly zero </li>
+<li><a href="geom2_r.c#maxouter">qh_maxouter</a> return maximum outer
+plane</li>
+<li><a href="geom2_r.c#outerinner">qh_outerinner</a> return actual
+outer and inner planes
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+
+
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/src/libqhullr/qh-globa.htm b/src/libqhull_r/qh-globa_r.htm
similarity index 51%
rename from src/libqhullr/qh-globa.htm
rename to src/libqhull_r/qh-globa_r.htm
index 51a4611..04667ed 100644
--- a/src/libqhullr/qh-globa.htm
+++ b/src/libqhull_r/qh-globa_r.htm
@@ -1,161 +1,160 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
-<title>global.c -- global variables and their functions</title>
+<title>global_r.c -- global variables and their functions</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm#TOC">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<!-- Main text of document. -->
-<h2>global.c -- global variables and their functions</h2>
+<h2>global_r.c -- global variables and their functions</h2>
<blockquote>
-<p>Qhull uses a global data structure, <tt>qh</tt>, 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
-<a href="user.h#QHpointer">QHpointer</a>.
+<p>Qhull uses a data structure, <tt>qhT</tt>, to store
+globally defined constants, lists, sets, and variables. It is passed as the
+first argument to each procedure.
</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <b>Global</b> &#149;
-<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
-<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
-<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
-<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
+<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a> &#149;
+<a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a> &#149;
+<a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a> </p>
-<h3>Index to <a href="global.c">global.c</a> and
-<a href="libqhull.h">libqhull.h</a></h3>
+<h3>Index to <a href="global_r.c">global_r.c</a> and
+<a href="libqhull_r.h">libqhull_r.h</a></h3>
<ul>
<li><a href="#ovar">Qhull's global variables</a> </li>
<li><a href="#ofunc">Global variable and initialization
routines</a> </li>
</ul>
-<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ovar">Qhull's global
+<h3><a href="qh-globa_r.htm#TOC">&#187;</a><a name="ovar">Qhull's global
variables</a></h3>
<ul>
-<li><a href=global.c#qh_version>qh_version</a> version string
-<li><a href="libqhull.h#qh">qh</a> all global variables for
+<li><a href=global_r.c#qh_version>qh_version</a> version string
+<li><a href="libqhull_r.h#qh">qh</a> all global variables for
qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
-<li><a href="libqhull.h#qh-const">qh constants</a> configuration
+<li><a href="libqhull_r.h#qh-const">qh constants</a> configuration
flags and constants for Qhull </li>
-<li><a href="libqhull.h#qh-prec">qh precision constants</a>
+<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
-<li><a href="libqhull.h#qh-codetern">qh internal constants</a>
+<li><a href="libqhull_r.h#qh-codetern">qh internal constants</a>
internal constants for Qhull </li>
-<li><a href="libqhull.h#qh-lists">qh facet and vertex lists</a>
+<li><a href="libqhull_r.h#qh-lists">qh facet and vertex lists</a>
lists of facets and vertices </li>
-<li><a href="libqhull.h#qh-var">qh global variables</a> minimum
+<li><a href="libqhull_r.h#qh-var">qh global variables</a> minimum
and maximum distances, next visit ids, several flags, and
other global variables. </li>
-<li><a href="libqhull.h#qh-set">qh global sets</a> global sets
+<li><a href="libqhull_r.h#qh-set">qh global sets</a> global sets
for merging, hashing, input, etc. </li>
-<li><a href="libqhull.h#qh-buf">qh global buffers</a> buffers
+<li><a href="libqhull_r.h#qh-buf">qh global buffers</a> buffers
for matrix operations and input </li>
-<li><a href="libqhull.h#qh-static">qh static variables</a>
+<li><a href="libqhull_r.h#qh-static">qh static variables</a>
static variables for individual functions </li>
</ul>
-<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ofunc">Global variable and
+<h3><a href="qh-globa_r.htm#TOC">&#187;</a><a name="ofunc">Global variable and
initialization routines</a></h3>
<ul>
-<li><a href="global.c#appendprint">qh_appendprint</a> append
+<li><a href="global_r.c#appendprint">qh_appendprint</a> append
output format to <tt>qh.PRINTout</tt> </li>
-<li><a href="global.c#freebuffers">qh_freebuffers</a> free
+<li><a href="global_r.c#freebuffers">qh_freebuffers</a> free
global memory buffers </li>
-<li><a href="global.c#freeqhull">qh_freeqhull</a> free memory
+<li><a href="global_r.c#freeqhull">qh_freeqhull</a> free memory
used by qhull </li>
-<li><a href="global.c#init_A">qh_init_A</a> called before
+<li><a href="global_r.c#init_A">qh_init_A</a> called before
error handling initialized </li>
-<li><a href="global.c#init_B">qh_init_B</a> called after
+<li><a href="global_r.c#init_B">qh_init_B</a> called after
points are defined </li>
-<li><a href="global.c#init_qhull_command">qh_init_qhull_command</a>
+<li><a href="global_r.c#init_qhull_command">qh_init_qhull_command</a>
build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
-<li><a href="global.c#initflags">qh_initflags</a> set flags
+<li><a href="global_r.c#initflags">qh_initflags</a> set flags
and constants from command line </li>
-<li><a href="global.c#initqhull_buffers">qh_initqhull_buffers</a>
+<li><a href="global_r.c#initqhull_buffers">qh_initqhull_buffers</a>
initialize global memory buffers </li>
-<li><a href="global.c#initqhull_globals">qh_initqhull_globals</a>
+<li><a href="global_r.c#initqhull_globals">qh_initqhull_globals</a>
initialize global variables </li>
-<li><a href="global.c#initqhull_mem">qh_initqhull_mem</a>
+<li><a href="global_r.c#initqhull_mem">qh_initqhull_mem</a>
initialize Qhull memory management </li>
-<li><a href="global.c#initqhull_start">qh_initqhull_start</a>
+<li><a href="global_r.c#initqhull_start">qh_initqhull_start</a>
allocate qh_qh and call qh_initqhull_start2()
-<li><a href="global.c#initqhull_start2">qh_initqhull_start2</a>
+<li><a href="global_r.c#initqhull_start2">qh_initqhull_start2</a>
initialize default values at Qhull startup </li>
-<li><a href="global.c#initthresholds">qh_initthresholds</a>
+<li><a href="global_r.c#initthresholds">qh_initthresholds</a>
initialize 'Pdn' and 'PDn' thresholds </li>
-<li><a href="global.c#option">qh_option</a> append option
+<li><a href="global_r.c#lib_check">qh_lib_check</a> check for compatible Qhull library</li>
+<li><a href="global_r.c#option">qh_option</a> append option
description to <tt>qh.global_options</tt> </li>
-<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
+<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
restores a previously saved qhull </li>
-<li><a href="global.c#save_qhull">qh_save_qhull</a> saves
+<li><a href="global_r.c#save_qhull">qh_save_qhull</a> saves
qhull for a later qh_restore_qhull() </li>
-<li><a href="global.c#strtol">qh_strtol</a> duplicates
+<li><a href="global_r.c#strtol">qh_strtol</a> duplicates
strtod() and strtol() </li>
+<li><a href="global_r.c#zero">qh_zero</a> zeroes qhT before first use</li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhull_r/qh-io_r.htm b/src/libqhull_r/qh-io_r.htm
new file mode 100644
index 0000000..096467d
--- /dev/null
+++ b/src/libqhull_r/qh-io_r.htm
@@ -0,0 +1,303 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>io_r.c -- input and output operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>io_r.c -- input and output operations</h2>
+<blockquote>
+
+<p>Qhull provides a wide range of input
+and output options. To organize the code, most output formats use
+the same driver: </p>
+
+<pre>
+ 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 );
+</pre>
+
+<p>Note the 'printall' flag. It selects whether or not
+qh_skipfacet() is tested. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a> <a name="TOC">&#149;</a>
+<a href="qh-globa_r.htm#TOC">Global</a> &#149; <b>Io</b> &#149;
+<a href="qh-mem_r.htm#TOC">Mem</a> &#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149;
+<a href="qh-poly_r.htm#TOC">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149;
+<a href="qh-set_r.htm#TOC">Set</a> &#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149;
+<a href="qh-user_r.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="io_r.c">io_r.c</a> and <a href="io_r.h">io_r.h</a></h3>
+
+<ul>
+<li><a href="#iconst">io_r.h constants and types</a> </li>
+<li><a href="#ilevel">User level functions</a> </li>
+<li><a href="#iprint">Print functions for all output formats</a></li>
+<li><a href="#itext">Text output functions</a> </li>
+<li><a href="#iutil">Text utility functions</a></li>
+<li><a href="#igeom">Geomview output functions</a> </li>
+<li><a href="#iview">Geomview utility functions</a></li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iconst">io_r.h constants and types</a></h3>
+
+<ul>
+<li><a href="io_r.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
+of first two lines of stdin </li>
+<li><a href="io_r.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
+values of white space </li>
+<li><a href="io_r.h#printvridgeT">printvridgeT</a> function to
+print results of qh_printvdiagram or qh_eachvoronoi</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="ilevel">User level functions</a></h3>
+
+<ul>
+<li><a href="io_r.c#copyfilename">qh_copyfilename</a>
+copy filename identified by qh_skipfilename
+<li><a href="io_r.c#eachvoronoi_all">qh_eachvoronoi_all</a>
+visit each Voronoi ridge of the Voronoi diagram
+<li><a href="io_r.c#prepare_output">qh_prepare_output</a>
+prepare Qhull for output (called by qh_produce_output())
+<li><a href="io_r.c#printhelp_degenerate">qh_printhelp_degenerate</a>
+prints descriptive message for precision error </li>
+<li><a href="io_r.c#printhelp_singular">qh_printhelp_singular</a>
+print help message for singular data </li>
+<li><a href="libqhull_r.c#printsummary">qh_printsummary</a> print
+summary ('s')</li>
+<li><a href="io_r.c#produce_output">qh_produce_output</a>
+prints out the result of qhull()</li>
+<li><a href="io_r.c#produce_output">qh_produce_output2</a>
+prints out the result of qhull() without calling qh_prepare_output()</li>
+<li><a href="io_r.c#readfeasible">qh_readfeasible</a> read
+interior point from remainder and qh fin ('H')</li>
+<li><a href="io_r.c#readpoints">qh_readpoints</a> read input
+points </li>
+<li><a href="io_r.c#setfeasible">qh_setfeasible</a> set
+interior point from qh feasible_string ('Hn,n,n')</li>
+<li><a href="io_r.c#skipfilename">qh_skipfilename</a>
+skip filename in string
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iprint">Print functions for all
+output formats</a></h3>
+
+<ul>
+<li><a href="io_r.c#countfacets">qh_countfacets</a> count good
+facets for printing and set visitid </li>
+<li><a href="io_r.c#markkeep">qh_markkeep</a> mark good facets
+that meet qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
+<li><a href="io_r.c#order_vertexneighbors">qh_order_vertexneighbors</a>
+order neighbors for a 3-d vertex by adjacency ('i', 'o')</li>
+<li><a href="io_r.c#printafacet">qh_printafacet</a> print facet
+in an output format </li>
+<li><a href="io_r.c#printbegin">qh_printbegin</a> print header
+for an output format </li>
+<li><a href="io_r.c#printend">qh_printend</a> print trailer for
+an output format </li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print facets in a facetlist</li>
+<li><a href="io_r.c#printfacets">qh_printfacets</a> print
+facetlist and/or facet set in an output format </li>
+<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
+print neighborhood of one or two facets ('Po')</li>
+<li><a href="io_r.c#produce_output">qh_produce_output</a>
+print the results of qh_qhull() </li>
+<li><a href="io_r.c#skipfacet">qh_skipfacet</a> True if not
+printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
+<li><a href="io_r.c#facetvertices">qh_facetvertices</a> return
+vertices in a set of facets ('p')</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="itext">Text output functions</a></h3>
+<ul>
+<li><a href="io_r.c#eachvoronoi">qh_eachvoronoi</a>
+print or visit each Voronoi ridge for an input site of the Voronoi diagram
+<li><a href="io_r.c#printextremes">qh_printextremes</a> print
+extreme points by point ID (vertices of convex hull) ('Fx')</li>
+<li><a href="io_r.c#printextremes_2d">qh_printextremes_2d</a> print
+2-d extreme points by point ID ('Fx')</li>
+<li><a href="io_r.c#printextremes_d">qh_printextremes_d</a> print
+extreme points of input sites for Delaunay triangulations ('Fx')</li>
+<li><a href="io_r.c#printfacet">qh_printfacet</a> print all
+fields of a facet ('f')</li>
+<li><a href="io_r.c#printfacet2math">qh_printfacet2math</a> print
+2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
+<li><a href="io_r.c#printfacet3math">qh_printfacet3math</a>
+print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
+<li><a href="io_r.c#printfacet3vertex">qh_printfacet3vertex</a>
+print vertices for a 3-d facet ('i', 'o')</li>
+<li><a href="io_r.c#printfacetheader">qh_printfacetheader</a>
+prints header fields of a facet ('f')</li>
+<li><a href="io_r.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
+print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
+<li><a href="io_r.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
+print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
+<li><a href="io_r.c#printfacetridges">qh_printfacetridges</a>
+prints ridges of a facet ('f')</li>
+<li><a href="io_r.c#printpoints_out">qh_printpoints_out</a> prints
+vertices for facets by their point coordinates ('p')</li>
+<li><a href="io_r.c#printridge">qh_printridge</a> print all
+fields for a ridge ('f')</li>
+<li><a href="io_r.c#printvdiagram">qh_printvdiagram</a> print
+voronoi diagram as Voronoi vertices for each input pair</li>
+<li><a href="io_r.c#printvertex">qh_printvertex</a> print all
+fields for a vertex ('f')</li>
+<li><a href="io_r.c#printvertexlist">qh_printvertexlist</a>
+print vertices used by a list or set of facets ('f')</li>
+<li><a href="io_r.c#printvertices">qh_printvertices</a> print a
+set of vertices ('f')</li>
+<li><a href="io_r.c#printvneighbors">qh_printvneighbors</a>
+print vertex neighbors of vertices ('FN')</li>
+<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
+voronoi diagram in 'o' or 'G' format</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iutil">Text utility functions</a></h3>
+<ul>
+<li><a href="io_r.c#dfacet">dfacet</a> print facet by ID </li>
+<li><a href="io_r.c#dvertex">dvertex</a> print vertex by ID </li>
+<li><a href="io_r.c#compare_facetarea">qh_compare_facetarea</a>
+used by qsort() to order facets by area </li>
+<li><a href="io_r.c#compare_facetmerge">qh_compare_facetmerge</a>
+used by qsort() to order facets by number of merges </li>
+<li><a href="io_r.c#compare_facetvisit">qh_compare_facetvisit</a>
+used by qsort() to order facets by visit ID or ID </li>
+<li><a href="io_r.c#compare_vertexpoint">qh_compare_vertexpoint</a>
+used by qsort() to order vertices by point ID </li>
+<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
+<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
+ridge for an input site
+<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
+ridge for an input site
+<li><a href="io_r.c#facet2point">qh_facet2point</a> return two
+projected temporary vertices for a 2-d facet ('m', 'G')</li>
+<li><a href="io_r.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
+vertices for printing
+<li><a href="io_r.c#printcenter">qh_printcenter</a> print
+facet-&gt;center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
+<li><a href="io_r.c#printpoint">qh_printpoint</a>, qh_printpointid, print
+coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
+<li><a href="io_r.c#printpoint3">qh_printpoint3</a> prints 2-d,
+3-d, or 4-d point as 3-d coordinates ('G')</li>
+<li><a href="io_r.c#printvdiagram2">qh_printvdiagram2</a> print
+voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
+<li><a href="io_r.c#printvnorm">qh_printvnorm</a> print
+separating plane of the Voronoi diagram for a pair of input sites</li>
+<li><a href="io_r.c#printvridge">qh_printvridge</a> print
+ridge of the Voronoi diagram for a pair of input sites</li>
+<li><a href="io_r.c#projectdim3">qh_projectdim3</a> project 2-d
+3-d or 4-d point to a 3-d point ('G')</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="igeom">Geomview output functions</a></h3>
+<ul>
+<li><a href="io_r.c#printfacet2geom">qh_printfacet2geom</a>
+print facet as a 2-d VECT object </li>
+<li><a href="io_r.c#printfacet2geom_points">qh_printfacet2geom_points</a>
+print points as a 2-d VECT object with offset </li>
+<li><a href="io_r.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
+print Geomview OFF for a 3-d nonsimplicial facet. </li>
+<li><a href="io_r.c#printfacet3geom_points">qh_printfacet3geom_points</a>
+prints a 3-d facet as OFF Geomview object. </li>
+<li><a href="io_r.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
+print Geomview OFF for a 3-d simplicial facet. </li>
+<li><a href="io_r.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
+print Geomview 4OFF file for a 4d nonsimplicial facet </li>
+<li><a href="io_r.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
+print Geomview 4OFF file for a 4d simplicial facet </li>
+<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
+print hyperplane intersection as OFF or 4OFF </li>
+<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
+voronoi diagram in 'o' or 'G' format</li>
+</ul>
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iview">Geomview utility functions</a></h3>
+<ul>
+<li><a href="io_r.c#geomplanes">qh_geomplanes</a>
+ return outer and inner planes for Geomview</li>
+<li><a href="io_r.c#printcentrum">qh_printcentrum</a> print
+centrum for a facet in OOGL format </li>
+<li><a href="io_r.c#printend4geom">qh_printend4geom</a> helper
+function for qh_printbegin/printend </li>
+<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
+print Geomview OFF or 4OFF for the intersection of two
+hyperplanes in 3-d or 4-d </li>
+<li><a href="io_r.c#printline3geom">qh_printline3geom</a> prints a
+line as a VECT </li>
+<li><a href="io_r.c#printpointvect">qh_printpointvect</a>
+prints a 2-d or 3-d point as 3-d VECT's </li>
+<li><a href="io_r.c#printpointvect2">qh_printpointvect2</a>
+prints a 2-d or 3-d point as 2 3-d VECT's </li>
+<li><a href="io_r.c#printspheres">qh_printspheres</a> prints 3-d
+vertices as OFF spheres </li>
+</ul>
+<p>
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/src/libqhullr/qh-mem.htm b/src/libqhull_r/qh-mem_r.htm
similarity index 51%
rename from src/libqhullr/qh-mem.htm
rename to src/libqhull_r/qh-mem_r.htm
index 5aca0e1..5c4d107 100644
--- a/src/libqhullr/qh-mem.htm
+++ b/src/libqhull_r/qh-mem_r.htm
@@ -1,141 +1,143 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
-<title>mem.c -- memory operations</title>
+<title>mem_r.c -- memory operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
-<h2>mem.c -- memory operations</h2>
+<h2>mem_r.c -- memory operations</h2>
<blockquote>
<p>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. </p>
<p>Use 'T5' to trace memory allocations.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
-<a href="qh-io.htm#TOC">Io</a> &#149; <b>Mem</b>
-&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <b>Mem</b>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
-<h3>Index to <a href="mem.c">mem.c</a> and
-<a href="mem.h">mem.h</a></h3>
+<h3>Index to <a href="mem_r.c">mem_r.c</a> and
+<a href="mem_r.h">mem_r.h</a></h3>
<ul>
-<li><a href="#etype">mem.h data types</a> </li>
-<li><a href="#emacro">mem.h macros</a> </li>
+<li><a href="#etype">mem_r.h data types</a> </li>
+<li><a href="#emacro">mem_r.h macros</a> </li>
<li><a href="#efunc">User level functions</a> </li>
</ul>
-<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="etype">mem.h data types and constants</a></h3>
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="etype">mem_r.h data types and constants</a></h3>
<ul>
-<li><a href="mem.h#ptr_intT">ptr_intT</a> for casting
+<li><a href="mem_r.h#ptr_intT">ptr_intT</a> for casting
a void* to an integer-type </li>
-<li><a href="mem.h#qhmemT">qhmemT</a> global memory
-structure for mem.c </li>
-<li><a href="mem.h#NOmem">qh_NOmem</a> disable memory allocation</li>
+<li><a href="mem_r.h#qhmemT">qhmemT</a> global memory
+structure for mem_r.c </li>
+<li><a href="mem_r.h#NOmem">qh_NOmem</a> disable memory allocation</li>
</ul>
-<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="emacro">mem.h macros</a></h3>
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="emacro">mem_r.h macros</a></h3>
<ul>
-<li><a href="mem.h#memalloc_">qh_memalloc_</a>
+<li><a href="mem_r.h#memalloc_">qh_memalloc_</a>
allocate memory</li>
-<li><a href="mem.h#memfree_">qh_memfree_</a> free
+<li><a href="mem_r.h#memfree_">qh_memfree_</a> free
memory</li>
</ul>
-<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="efunc">User level
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="efunc">User level
functions</a></h3>
<ul>
-<li><a href="mem.c#memalloc">qh_memalloc</a> allocate
+<li><a href="mem_r.c#memalloc">qh_memalloc</a> allocate
memory </li>
-<li><a href="mem.c#memfree">qh_memfree</a> free
+<li><a href="mem_r.c#memcheck">qh_memcheck</a>
+quick check of memory for internal consistency</li>
+<li><a href="mem_r.c#memfree">qh_memfree</a> free
memory </li>
-<li><a href="mem.c#meminit">qh_meminit</a> initialize
+<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
memory </li>
-<li><a href="mem.c#memstatistics">qh_memstatistics</a>
+<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
print memory statistics </li>
-<li><a href="mem.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
-<li><a href="mem.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
+<li><a href="mem_r.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
+<li><a href="mem_r.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
</ul>
-<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="m">Initialization and
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="m">Initialization and
termination functions</a></h3>
<ul>
-<li><a href="mem.c#intcompare">qh_intcompare</a> used by
+<li><a href="mem_r.c#intcompare">qh_intcompare</a> used by
qsort and bsearch to compare two integers </li>
-<li><a href="mem.c#memfreeshort">qh_memfreeshort</a>
+<li><a href="mem_r.c#memfreeshort">qh_memfreeshort</a>
frees up all short and qhmem memory allocations </li>
-<li><a href="mem.c#meminit">qh_meminit</a> initialize
+<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
memory </li>
-<li><a href="mem.c#meminitbuffers">qh_meminitbuffers</a>
+<li><a href="mem_r.c#meminitbuffers">qh_meminitbuffers</a>
initialize qhmem </li>
-<li><a href="mem.c#memsetup">qh_memsetup</a> set up
+<li><a href="mem_r.c#memsetup">qh_memsetup</a> set up
memory after running memsize() </li>
-<li><a href="mem.c#memsize">qh_memsize</a> define a free
+<li><a href="mem_r.c#memsize">qh_memsize</a> define a free
list for this size </li>
-<li><a href="mem.c#memstatistics">qh_memstatistics</a>
+<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
print out memory statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhullr/qh-merge.htm b/src/libqhull_r/qh-merge_r.htm
similarity index 59%
rename from src/libqhullr/qh-merge.htm
rename to src/libqhull_r/qh-merge_r.htm
index 625c555..e04a3fb 100644
--- a/src/libqhullr/qh-merge.htm
+++ b/src/libqhull_r/qh-merge_r.htm
@@ -1,364 +1,364 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
-<title>merge.c -- facet merge operations</title>
+<title>merge_r.c -- facet merge operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
-<h2>merge.c -- facet merge operations</h2>
+<h2>merge_r.c -- facet merge operations</h2>
<blockquote>
<p>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 <a href="../../html/qh-impre.htm">Imprecision in Qhull</a>
for further information. </p>
<p>Users may joggle the input ('<a href="../../html/qh-optq.htm#QJn">QJn</a>')
instead of merging facets. </p>
<p>Qhull detects and corrects the following problems: </p>
<ul>
<li><b>More than two facets meeting at a ridge. </b>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 <em>duplicate
ridge</em>. In 2-d, a duplicate ridge would
create a loop of facets. </li>
</ul>
<ul>
<li><b>A facet contained in another facet. </b>Facet
merging may leave all vertices of one facet as a
subset of the vertices of another facet. This is
called a <em>redundant facet</em>. </li>
</ul>
<ul>
<li><b>A facet with fewer than three neighbors. </b>Facet
merging may leave a facet with one or two
neighbors. This is called a <em>degenerate facet</em>.
</li>
</ul>
<ul>
<li><b>A facet with flipped orientation. </b>A
facet's hyperplane may define a halfspace that
does not include the interior point.This is
called a <em>flipped facet</em>. </li>
</ul>
<ul>
<li><strong>A coplanar horizon facet.</strong> 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 <em>samecycle</em>.
The new facet or samecycle is merged into the
horizon facet. </li>
</ul>
<ul>
<li><b>Concave facets. </b>A facet's centrum may be
above a neighboring facet. If so, the facets meet
at a concave angle. </li>
</ul>
<ul>
<li><b>Coplanar facets. </b>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.</li>
</ul>
<ul>
<li><b>Redundant vertex. </b>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 <em>redundant vertex</em>.
</li>
</ul>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
-&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
-&#149; <b>Merge</b> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <b>Merge</b> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
-<h3>Index to <a href="merge.c">merge.c</a> and
-<a href="merge.h">merge.h</a></h3>
+<h3>Index to <a href="merge_r.c">merge_r.c</a> and
+<a href="merge_r.h">merge_r.h</a></h3>
<ul>
-<li><a href="#mtype">merge.h data types, macros, and
+<li><a href="#mtype">merge_r.h data types, macros, and
global sets</a> </li>
-<li><a href="#mconst">merge.h constants</a> </li>
+<li><a href="#mconst">merge_r.h constants</a> </li>
</ul>
<ul>
<li><a href="#mtop">top-level merge functions</a> </li>
<li><a href="#mset">functions for identifying merges</a></li>
<li><a href="#mbest">functions for determining the
best merge</a> </li>
<li><a href="#mmerge">functions for merging facets</a>
</li>
<li><a href="#mcycle">functions for merging a cycle
of facets</a> </li>
<li><a href="#mrename">functions for renaming a
vertex</a> </li>
<li><a href="#mvertex">functions for identifying
vertices for renaming</a> </li>
<li><a href="#mcheck">functions for check and trace</a> </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mtype">merge.h data
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mtype">merge_r.h data
types, macros, and global sets</a></h3>
<ul>
-<li><a href="merge.h#mergeT">mergeT</a> structure to
+<li><a href="merge_r.h#mergeT">mergeT</a> structure to
identify a merge of two facets</li>
-<li><a href="merge.h#FOREACHmerge_">FOREACHmerge_</a>
+<li><a href="merge_r.h#FOREACHmerge_">FOREACHmerge_</a>
assign 'merge' to each merge in merges </li>
-<li><a href="libqhull.h#qh-set">qh global sets</a>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a>
qh.facet_mergeset contains non-convex merges
while qh.degen_mergeset contains degenerate and
redundant facets</li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mconst">merge.h
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mconst">merge_r.h
constants</a></h3>
<ul>
-<li><a href="libqhull.h#qh-prec">qh precision constants</a>
+<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
-<li><a href="merge.h#MRG">MRG...</a> indicates the
+<li><a href="merge_r.h#MRG">MRG...</a> indicates the
type of a merge (mergeT-&gt;type)</li>
-<li><a href="merge.h#qh_ANGLEredundant">qh_ANGLEredundant</a>
+<li><a href="merge_r.h#qh_ANGLEredundant">qh_ANGLEredundant</a>
indicates redundant merge in mergeT-&gt;angle </li>
-<li><a href="merge.h#qh_ANGLEdegen">qh_ANGLEdegen</a>
+<li><a href="merge_r.h#qh_ANGLEdegen">qh_ANGLEdegen</a>
indicates degenerate facet in mergeT-&gt;angle </li>
-<li><a href="merge.h#qh_ANGLEconcave">qh_ANGLEconcave</a>
+<li><a href="merge_r.h#qh_ANGLEconcave">qh_ANGLEconcave</a>
offset to indicate concave facets in
mergeT-&gt;angle </li>
-<li><a href="merge.h#qh_MERGEapex">qh_MERGEapex</a>
+<li><a href="merge_r.h#qh_MERGEapex">qh_MERGEapex</a>
flag for qh_mergefacet() to indicate an apex
merge </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mtop">top-level merge
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mtop">top-level merge
functions</a></h3>
<ul>
-<li><a href="merge.c#all_merges">qh_all_merges</a>
+<li><a href="merge_r.c#all_merges">qh_all_merges</a>
merge all non-convex facets </li>
-<li><a href="merge.c#checkzero">qh_checkzero</a>
+<li><a href="merge_r.c#checkzero">qh_checkzero</a>
check that facets are clearly convex </li>
-<li><a href="merge.c#flippedmerges">qh_flippedmerges</a>
+<li><a href="merge_r.c#flippedmerges">qh_flippedmerges</a>
merge flipped facets into best neighbor </li>
-<li><a href="merge.c#forcedmerges">qh_forcedmerges</a>
+<li><a href="merge_r.c#forcedmerges">qh_forcedmerges</a>
merge all duplicate ridges </li>
-<li><a href="merge.c#merge_degenredundant">qh_merge_degenredundant</a>
+<li><a href="merge_r.c#merge_degenredundant">qh_merge_degenredundant</a>
merge degenerate and redundant facets </li>
-<li><a href="merge.c#merge_nonconvex">qh_merge_nonconvex</a>
+<li><a href="merge_r.c#merge_nonconvex">qh_merge_nonconvex</a>
merge a non-convex ridge </li>
-<li><a href="merge.c#premerge">qh_premerge</a>
+<li><a href="merge_r.c#premerge">qh_premerge</a>
pre-merge non-convex facets </li>
-<li><a href="merge.c#postmerge">qh_postmerge</a>
+<li><a href="merge_r.c#postmerge">qh_postmerge</a>
post-merge nonconvex facets as defined by
maxcentrum/maxangle </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mset">functions for
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mset">functions for
identifying merges</a></h3>
<ul>
-<li><a href="merge.c#appendmergeset">qh_appendmergeset</a>
+<li><a href="merge_r.c#appendmergeset">qh_appendmergeset</a>
appends an entry to qh.facet_mergeset</li>
-<li><a href="merge.c#compareangle">qh_compareangle</a>
+<li><a href="merge_r.c#compareangle">qh_compareangle</a>
used by qsort() to order merges </li>
-<li><a href="merge.c#comparemerge">qh_comparemerge</a>
+<li><a href="merge_r.c#comparemerge">qh_comparemerge</a>
used by qsort() to order merges </li>
-<li><a href="merge.c#degen_redundant_facet">qh_degen_redundant_facet</a>
+<li><a href="merge_r.c#degen_redundant_facet">qh_degen_redundant_facet</a>
check for a degenerate and redundant facet</li>
-<li><a href="merge.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
+<li><a href="merge_r.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
append degenerate and redundant neighbors to
qh.degen_mergeset </li>
-<li><a href="merge.c#getmergeset_initial">qh_getmergeset_initial</a>
+<li><a href="merge_r.c#getmergeset_initial">qh_getmergeset_initial</a>
build initial qh.facet_mergeset </li>
-<li><a href="merge.c#getmergeset">qh_getmergeset</a>
+<li><a href="merge_r.c#getmergeset">qh_getmergeset</a>
update qh.facet_mergeset </li>
-<li><a href="merge.c#mark_dupridges">qh_mark_dupridges</a>
+<li><a href="merge_r.c#mark_dupridges">qh_mark_dupridges</a>
add duplicated ridges to qh.facet_mergeset</li>
-<li><a href="merge.c#maydropneighbor">qh_maydropneighbor</a>
+<li><a href="merge_r.c#maydropneighbor">qh_maydropneighbor</a>
drop neighbor relationship if no ridge between
facet and neighbor </li>
-<li><a href="merge.c#test_appendmerge">qh_test_appendmerge</a>
+<li><a href="merge_r.c#test_appendmerge">qh_test_appendmerge</a>
test a pair of facets for convexity and append to
qh.facet_mergeset if non-convex </li>
-<li><a href="merge.c#test_vneighbors">qh_test_vneighbors</a>
+<li><a href="merge_r.c#test_vneighbors">qh_test_vneighbors</a>
test vertex neighbors for convexity </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mbest">functions for
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mbest">functions for
determining the best merge</a></h3>
<ul>
-<li><a href="merge.c#findbest_test">qh_findbest_test</a>
+<li><a href="merge_r.c#findbest_test">qh_findbest_test</a>
test neighbor for best merge </li>
-<li><a href="merge.c#findbestneighbor">qh_findbestneighbor</a>
+<li><a href="merge_r.c#findbestneighbor">qh_findbestneighbor</a>
finds best neighbor of a facet for merging (i.e.,
closest hyperplane) </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mmerge">functions for
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mmerge">functions for
merging facets</a></h3>
<ul>
-<li><a href="merge.c#copynonconvex">qh_copynonconvex</a>
+<li><a href="merge_r.c#copynonconvex">qh_copynonconvex</a>
copy non-convex flag to another ridge for the
same neighbor </li>
-<li><a href="merge.c#makeridges">qh_makeridges</a>
+<li><a href="merge_r.c#makeridges">qh_makeridges</a>
creates explicit ridges between simplicial facets
</li>
-<li><a href="merge.c#mergefacet">qh_mergefacet</a>
+<li><a href="merge_r.c#mergefacet">qh_mergefacet</a>
merges one facet into another facet</li>
-<li><a href="merge.c#mergeneighbors">qh_mergeneighbors</a>
+<li><a href="merge_r.c#mergeneighbors">qh_mergeneighbors</a>
merges the neighbors of two facets </li>
-<li><a href="merge.c#mergeridges">qh_mergeridges</a>
+<li><a href="merge_r.c#mergeridges">qh_mergeridges</a>
merges the ridge sets of two facets </li>
-<li><a href="merge.c#mergesimplex">qh_mergesimplex</a>
+<li><a href="merge_r.c#mergesimplex">qh_mergesimplex</a>
merge a simplicial facet into another simplicial
facet </li>
-<li><a href="merge.c#mergevertex_del">qh_mergevertex_del</a>
+<li><a href="merge_r.c#mergevertex_del">qh_mergevertex_del</a>
delete a vertex due to merging one facet into
another facet </li>
-<li><a href="merge.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
+<li><a href="merge_r.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
merge the vertex neighbors of two facets </li>
-<li><a href="merge.c#mergevertices">qh_mergevertices</a>
+<li><a href="merge_r.c#mergevertices">qh_mergevertices</a>
merge the vertex sets of two facets </li>
-<li><a href="merge.c#newvertices">qh_newvertices</a>
+<li><a href="merge_r.c#newvertices">qh_newvertices</a>
register all vertices as new vertices </li>
-<li><a href="merge.c#updatetested">qh_updatetested</a>
+<li><a href="merge_r.c#updatetested">qh_updatetested</a>
clear tested flags and centrums involved in a
merge </li>
-<li><a href="merge.c#willdelete">qh_willdelete</a>
+<li><a href="merge_r.c#willdelete">qh_willdelete</a>
moves facet to qh.visible_list; sets replacement
or NULL </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mcycle">functions for
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mcycle">functions for
merging a cycle of facets</a></h3>
<p>If a point is coplanar with an horizon facet, the
corresponding new facets are linked together (a <em>samecycle</em>)
for merging.</p>
<ul>
-<li><a href="merge.c#basevertices">qh_basevertices</a>
+<li><a href="merge_r.c#basevertices">qh_basevertices</a>
return temporary set of base vertices for a
samecycle </li>
-<li><a href="merge.c#mergecycle">qh_mergecycle</a>
+<li><a href="merge_r.c#mergecycle">qh_mergecycle</a>
merge a samecycle into a horizon facet </li>
-<li><a href="merge.c#mergecycle_all">qh_mergecycle_all</a>
+<li><a href="merge_r.c#mergecycle_all">qh_mergecycle_all</a>
merge all samecycles into horizon facets</li>
-<li><a href="merge.c#mergecycle_facets">qh_mergecycle_facets</a>
+<li><a href="merge_r.c#mergecycle_facets">qh_mergecycle_facets</a>
finish merge of samecycle </li>
-<li><a href="merge.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
+<li><a href="merge_r.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
merge neighbor sets for samecycle </li>
-<li><a href="merge.c#mergecycle_ridges">qh_mergecycle_ridges</a>
+<li><a href="merge_r.c#mergecycle_ridges">qh_mergecycle_ridges</a>
merge ridge sets for samecycle </li>
-<li><a href="merge.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
+<li><a href="merge_r.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
merge vertex neighbor sets for samecycle </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mrename">functions
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mrename">functions
for renaming a vertex</a></h3>
<ul>
-<li><a href="merge.c#comparevisit">qh_comparevisit</a>
+<li><a href="merge_r.c#comparevisit">qh_comparevisit</a>
used by qsort() to order vertices by visitid</li>
-<li><a href="merge.c#reducevertices">qh_reducevertices</a>
+<li><a href="merge_r.c#reducevertices">qh_reducevertices</a>
reduce vertex sets </li>
-<li><a href="merge.c#redundant_vertex">qh_redundant_vertex</a>
+<li><a href="merge_r.c#redundant_vertex">qh_redundant_vertex</a>
returns true if detect and rename redundant
vertex </li>
-<li><a href="merge.c#rename_sharedvertex">qh_rename_sharedvertex</a>
+<li><a href="merge_r.c#rename_sharedvertex">qh_rename_sharedvertex</a>
detect and rename a shared vertex </li>
-<li><a href="merge.c#renameridgevertex">qh_renameridgevertex</a>
+<li><a href="merge_r.c#renameridgevertex">qh_renameridgevertex</a>
rename oldvertex to newvertex in a ridge </li>
-<li><a href="merge.c#renamevertex">qh_renamevertex</a>
+<li><a href="merge_r.c#renamevertex">qh_renamevertex</a>
rename oldvertex to newvertex in ridges </li>
-<li><a href="merge.c#remove_extravertices">qh_remove_extravertices</a>
+<li><a href="merge_r.c#remove_extravertices">qh_remove_extravertices</a>
remove extra vertices in non-simplicial facets </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mvertex">functions
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mvertex">functions
for identifying vertices for renaming</a></h3>
<ul>
-<li><a href="merge.c#find_newvertex">qh_find_newvertex</a>
+<li><a href="merge_r.c#find_newvertex">qh_find_newvertex</a>
locate new vertex for renaming old vertex </li>
-<li><a href="merge.c#hashridge">qh_hashridge</a> add
+<li><a href="merge_r.c#hashridge">qh_hashridge</a> add
ridge to hashtable </li>
-<li><a href="merge.c#hashridge_find">qh_hashridge_find</a>
+<li><a href="merge_r.c#hashridge_find">qh_hashridge_find</a>
returns matching ridge in hashtable</li>
-<li><a href="merge.c#neighbor_intersections">qh_neighbor_intersections</a>
+<li><a href="merge_r.c#neighbor_intersections">qh_neighbor_intersections</a>
return intersection of vertex sets for
neighboring facets </li>
-<li><a href="merge.c#vertexridges">qh_vertexridges</a>
+<li><a href="merge_r.c#vertexridges">qh_vertexridges</a>
return temporary set of ridges adjacent to a
vertex </li>
-<li><a href="merge.c#vertexridges_facet">qh_vertexridges_facet</a>
+<li><a href="merge_r.c#vertexridges_facet">qh_vertexridges_facet</a>
add adjacent ridges for a vertex in facet </li>
</ul>
-<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mcheck">functions for check and
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mcheck">functions for check and
trace</a></h3>
<ul>
-<li><a href="merge.c#checkconnect">qh_checkconnect</a>
+<li><a href="merge_r.c#checkconnect">qh_checkconnect</a>
check that new facets are connected </li>
-<li><a href="merge.c#tracemerge">qh_tracemerge</a>
+<li><a href="merge_r.c#tracemerge">qh_tracemerge</a>
print trace message after merge </li>
-<li><a href="merge.c#tracemerging">qh_tracemerging</a>
+<li><a href="merge_r.c#tracemerging">qh_tracemerging</a>
print trace message during post-merging </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhullr/qh-poly.htm b/src/libqhull_r/qh-poly_r.htm
similarity index 57%
rename from src/libqhullr/qh-poly.htm
rename to src/libqhull_r/qh-poly_r.htm
index abab924..e45261a 100644
--- a/src/libqhullr/qh-poly.htm
+++ b/src/libqhull_r/qh-poly_r.htm
@@ -1,481 +1,481 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
-<title>poly.c, poly2.c -- polyhedron operations</title>
+<title>poly_r.c, poly2_r.c -- polyhedron operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
-<h2>poly.c, poly2.c -- polyhedron operations</h2>
+<h2>poly_r.c, poly2_r.c -- polyhedron operations</h2>
<blockquote>
<p>Qhull uses dimension-free terminology. Qhull builds a
polyhedron in dimension <em>d. </em>A <em>polyhedron</em> is a
simplicial complex of faces with geometric information for the
top and bottom-level faces. A (<em>d-1</em>)-face is a <em>facet</em>,
a (<em>d-2</em>)-face is a <em>ridge</em>, and a <em>0</em>-face
is a <em>vertex</em>. For example in 3-d, a facet is a polygon
and a ridge is an edge. A facet is built from a ridge (the <em>base</em>)
and a vertex (the <em>apex</em>). See
<a href="../../html/index.htm#structure">Qhull's data structures</a>.</p>
<p>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 <em>a, b, c, d</em>, and its facets
are <em>1, 2, 3, 4,</em> the tetrahedron is </p>
<blockquote>
<ul>
<li>facet 1 <ul>
<li>vertices: b c d </li>
<li>neighbors: 2 3 4 </li>
</ul>
</li>
<li>facet 2 <ul>
<li>vertices: a c d </li>
<li>neighbors: 1 3 4 </li>
</ul>
</li>
<li>facet 3 <ul>
<li>vertices: a b d </li>
<li>neighbors: 1 2 4 </li>
</ul>
</li>
<li>facet 4 <ul>
<li>vertices: a b c </li>
<li>neighbors: 1 2 3 </li>
</ul>
</li>
</ul>
</blockquote>
<p>A facet may be simplicial or non-simplicial. In 3-d, a
<i>simplicial facet</i> has three vertices and three
neighbors. A <i>nonsimplicial facet</i> has more than
three vertices and more than three neighbors. A
nonsimplicial facet has a set of ridges and a centrum. </p>
<p>
A simplicial facet has an orientation. An <i>orientation</i>
is either <i>top</i> or <i>bottom</i>.
The flag, <tt>facet-&gt;toporient,</tt>
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.
<p>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, <tt>facet-&gt;toporient,</tt>is
ignored. </p>
<p>A nonsimplicial facet has a centrum for testing
convexity. A <i>centrum</i> 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. </p>
<p>A nonsimplicial facet is an approximation that is
defined by offsets from the facet's hyperplane. When
Qhull finishes, the <i>outer plane</i> is above all
points while the <i>inner plane</i> 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 <tt>facet-&gt;maxoutside</tt> while
the inner plane is computed from the facet's vertices.</p>
<p>Qhull 3.1 includes triangulation of non-simplicial facets
('<A href="../../html/qh-optq.htm#Qt">Qt</A>').
These facets,
called <i>tricoplanar</i>, 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.
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
-&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
-&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <b>Poly</b>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <b>Poly</b>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
-<h3>Index to <a href="poly.c">poly.c</a>,
-<a href="poly2.c">poly2.c</a>, <a href="poly.h">poly.h</a>,
-and <a href="libqhull.h">libqhull.h</a></h3>
+<h3>Index to <a href="poly_r.c">poly_r.c</a>,
+<a href="poly2_r.c">poly2_r.c</a>, <a href="poly_r.h">poly_r.h</a>,
+and <a href="libqhull_r.h">libqhull_r.h</a></h3>
<ul>
<li><a href="#ptype">Data types and global
lists for polyhedrons</a> </li>
-<li><a href="#pconst">poly.h constants</a> </li>
+<li><a href="#pconst">poly_r.h constants</a> </li>
<li><a href="#pgall">Global FORALL macros</a> </li>
<li><a href="#pall">FORALL macros</a> </li>
<li><a href="#peach">FOREACH macros</a> </li>
<li><a href="#pieach">Indexed FOREACH macros</a> </li>
<li><a href="#pmacro">Other macros for polyhedrons</a><p>&nbsp;</li>
<li><a href="#plist">Facetlist functions</a> </li>
<li><a href="#pfacet">Facet functions</a> </li>
<li><a href="#pvertex">Vertex, ridge, and point
functions</a> </li>
<li><a href="#phash">Hashtable functions</a> </li>
<li><a href="#pnew">Allocation and deallocation
functions</a> </li>
<li><a href="#pcheck">Check functions</a> </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="ptype">Data
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="ptype">Data
types and global lists for polyhedrons</a></h3>
<ul>
-<li><a href="libqhull.h#facetT">facetT</a> defines a
+<li><a href="libqhull_r.h#facetT">facetT</a> defines a
facet </li>
-<li><a href="libqhull.h#ridgeT">ridgeT</a> defines a
+<li><a href="libqhull_r.h#ridgeT">ridgeT</a> defines a
ridge </li>
-<li><a href="libqhull.h#vertexT">vertexT</a> defines a
+<li><a href="libqhull_r.h#vertexT">vertexT</a> defines a
vertex </li>
-<li><a href="libqhull.h#qh-lists">qh facet and vertex
+<li><a href="libqhull_r.h#qh-lists">qh facet and vertex
lists</a> lists of facets and vertices </li>
-<li><a href="libqhull.h#qh-set">qh global sets</a>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a>
global sets for merging, hashing, input, etc. </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pconst">poly.h constants</a></h3>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pconst">poly_r.h constants</a></h3>
<ul>
-<li><a href="poly.h#ALGORITHMfault">ALGORITHMfault</a>
+<li><a href="poly_r.h#ALGORITHMfault">ALGORITHMfault</a>
flag to not report errors in qh_checkconvex() </li>
-<li><a href="poly.h#DATAfault">DATAfault</a> flag to
+<li><a href="poly_r.h#DATAfault">DATAfault</a> flag to
report errors in qh_checkconvex() </li>
-<li><a href="poly.h#DUPLICATEridge">DUPLICATEridge</a>
+<li><a href="poly_r.h#DUPLICATEridge">DUPLICATEridge</a>
special value for facet-&gt;neighbor to indicate
a duplicate ridge </li>
-<li><a href="poly.h#MERGEridge">MERGEridge</a>
+<li><a href="poly_r.h#MERGEridge">MERGEridge</a>
special value for facet-&gt;neighbor to indicate
a merged ridge </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pgall">Global FORALL
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pgall">Global FORALL
macros</a></h3>
<ul>
-<li><a href="libqhull.h#FORALLfacets">FORALLfacets</a>
+<li><a href="libqhull_r.h#FORALLfacets">FORALLfacets</a>
assign 'facet' to each facet in qh.facet_list </li>
-<li><a href="poly.h#FORALLnew_facets">FORALLnew_facets</a>
+<li><a href="poly_r.h#FORALLnew_facets">FORALLnew_facets</a>
assign 'facet' to each facet in qh.newfacet_list </li>
-<li><a href="poly.h#FORALLvisible_facets">FORALLvisible_facets</a>
+<li><a href="poly_r.h#FORALLvisible_facets">FORALLvisible_facets</a>
assign 'visible' to each visible facet in
qh.visible_list </li>
-<li><a href="libqhull.h#FORALLpoints">FORALLpoints</a>
+<li><a href="libqhull_r.h#FORALLpoints">FORALLpoints</a>
assign 'point' to each point in qh.first_point,
qh.num_points </li>
-<li><a href="libqhull.h#FORALLvertices">FORALLvertices</a>
+<li><a href="libqhull_r.h#FORALLvertices">FORALLvertices</a>
assign 'vertex' to each vertex in qh.vertex_list </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pall">FORALL macros</a></h3>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pall">FORALL macros</a></h3>
<ul>
-<li><a href="poly.h#FORALLfacet_">FORALLfacet_</a>
+<li><a href="poly_r.h#FORALLfacet_">FORALLfacet_</a>
assign 'facet' to each facet in facetlist </li>
-<li><a href="libqhull.h#FORALLpoint_">FORALLpoint_</a>
+<li><a href="libqhull_r.h#FORALLpoint_">FORALLpoint_</a>
assign 'point' to each point in points array</li>
-<li><a href="poly.h#FORALLsame_">FORALLsame_</a>
+<li><a href="poly_r.h#FORALLsame_">FORALLsame_</a>
assign 'same' to each facet in samecycle</li>
-<li><a href="poly.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
+<li><a href="poly_r.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
assign 'same' to each facet in samecycle</li>
-<li><a href="poly.h#FORALLvertex_">FORALLvertex_</a>
+<li><a href="poly_r.h#FORALLvertex_">FORALLvertex_</a>
assign 'vertex' to each vertex in vertexlist </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="peach">FOREACH macros</a></h3>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="peach">FOREACH macros</a></h3>
<ul>
-<li><a href="libqhull.h#FOREACHfacet_">FOREACHfacet_</a>
+<li><a href="libqhull_r.h#FOREACHfacet_">FOREACHfacet_</a>
assign 'facet' to each facet in facets </li>
-<li><a href="libqhull.h#FOREACHneighbor_">FOREACHneighbor_</a>
+<li><a href="libqhull_r.h#FOREACHneighbor_">FOREACHneighbor_</a>
assign 'neighbor' to each facet in
facet-&gt;neighbors or vertex-&gt;neighbors</li>
-<li><a href="poly.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
+<li><a href="poly_r.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
assign 'newfacet' to each facet in facet set </li>
-<li><a href="libqhull.h#FOREACHpoint_">FOREACHpoint_</a>
+<li><a href="libqhull_r.h#FOREACHpoint_">FOREACHpoint_</a>
assign 'point' to each point in points set </li>
-<li><a href="libqhull.h#FOREACHridge_">FOREACHridge_</a>
+<li><a href="libqhull_r.h#FOREACHridge_">FOREACHridge_</a>
assign 'ridge' to each ridge in ridge set </li>
-<li><a href="libqhull.h#FOREACHvertex_">FOREACHvertex_</a>
+<li><a href="libqhull_r.h#FOREACHvertex_">FOREACHvertex_</a>
assign 'vertex' to each vertex in vertex set </li>
-<li><a href="poly.h#FOREACHvertexA_">FOREACHvertexA_</a>
+<li><a href="poly_r.h#FOREACHvertexA_">FOREACHvertexA_</a>
assign 'vertexA' to each vertex in vertex set</li>
-<li><a href="poly.h#FOREACHvisible_">FOREACHvisible_</a>
+<li><a href="poly_r.h#FOREACHvisible_">FOREACHvisible_</a>
assign 'visible' to each facet in facet set </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pieach">Indexed
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pieach">Indexed
FOREACH macros</a></h3>
<ul>
-<li><a href="libqhull.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
+<li><a href="libqhull_r.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
assign 'facet' and 'facet_i' to each facet in
facet set </li>
-<li><a href="libqhull.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
+<li><a href="libqhull_r.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
assign 'neighbor' and 'neighbor_i' to each facet
in facet-&gt;neighbors or vertex-&gt;neighbors</li>
-<li><a href="libqhull.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
+<li><a href="libqhull_r.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
assign 'point' and 'point_i' to each point in
points set </li>
-<li><a href="libqhull.h#FOREACHridge_i_">FOREACHridge_i_</a>
+<li><a href="libqhull_r.h#FOREACHridge_i_">FOREACHridge_i_</a>
assign 'ridge' and 'ridge_i' to each ridge in
ridges set </li>
-<li><a href="libqhull.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
+<li><a href="libqhull_r.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
assign 'vertex' and 'vertex_i' to each vertex in
vertices set </li>
-<li><a href="poly.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
+<li><a href="poly_r.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
assign 'vertex' to each vertex in vertex set;
reverse the order of first two vertices </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pmacro">Other macros for polyhedrons</a></h3>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pmacro">Other macros for polyhedrons</a></h3>
<ul>
-<li><a href="libqhull.h#getid_">getid_</a> return ID for
+<li><a href="libqhull_r.h#getid_">getid_</a> return ID for
a facet, ridge, or vertex </li>
-<li><a href="libqhull.h#otherfacet_">otherfacet_</a>
+<li><a href="libqhull_r.h#otherfacet_">otherfacet_</a>
return neighboring facet for a ridge in a facet </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="plist">Facetlist
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="plist">Facetlist
functions</a></h3>
<ul>
-<li><a href="poly.c#appendfacet">qh_appendfacet</a>
+<li><a href="poly_r.c#appendfacet">qh_appendfacet</a>
appends facet to end of qh.facet_list</li>
-<li><a href="poly.c#attachnewfacets">qh_attachnewfacets</a>
+<li><a href="poly_r.c#attachnewfacets">qh_attachnewfacets</a>
attach new facets in qh.newfacet_list to the
horizon </li>
-<li><a href="poly2.c#findgood">qh_findgood</a>
+<li><a href="poly2_r.c#findgood">qh_findgood</a>
identify good facets for qh.PRINTgood </li>
-<li><a href="poly2.c#findgood_all">qh_findgood_all</a>
+<li><a href="poly2_r.c#findgood_all">qh_findgood_all</a>
identify more good facets for qh.PRINTgood </li>
-<li><a href="poly2.c#furthestnext">qh_furthestnext</a>
+<li><a href="poly2_r.c#furthestnext">qh_furthestnext</a>
move facet with furthest of furthest points to
facet_next </li>
-<li><a href="poly2.c#initialhull">qh_initialhull</a>
+<li><a href="poly2_r.c#initialhull">qh_initialhull</a>
construct the initial hull as a simplex of
vertices </li>
-<li><a href="poly2.c#nearcoplanar">qh_nearcoplanar</a>
+<li><a href="poly2_r.c#nearcoplanar">qh_nearcoplanar</a>
remove near-inside points from coplanar sets</li>
-<li><a href="poly2.c#prependfacet">qh_prependfacet</a>
+<li><a href="poly2_r.c#prependfacet">qh_prependfacet</a>
prepends facet to start of facetlist </li>
-<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
print facets in a facetlist</li>
-<li><a href="poly2.c#printlists">qh_printlists</a>
+<li><a href="poly2_r.c#printlists">qh_printlists</a>
print out facet list for debugging </li>
-<li><a href="poly.c#removefacet">qh_removefacet</a>
+<li><a href="poly_r.c#removefacet">qh_removefacet</a>
unlinks facet from qh.facet_list</li>
-<li><a href="poly2.c#resetlists">qh_resetlists</a>
+<li><a href="poly2_r.c#resetlists">qh_resetlists</a>
reset qh.newvertex_list, qh.newfacet_list, and
qh.visible_list </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pfacet">Facet
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pfacet">Facet
functions</a></h3>
<ul>
-<li><a href="poly2.c#createsimplex">qh_createsimplex</a>
+<li><a href="poly2_r.c#createsimplex">qh_createsimplex</a>
create a simplex of facets from a set of vertices
</li>
-<li><a href="poly2.c#findbestlower">qh_findbestlower</a> find best
+<li><a href="poly2_r.c#findbestlower">qh_findbestlower</a> find best
non-upper, non-flipped facet for point at upperfacet</li>
-<li><a href="poly2.c#furthestout">qh_furthestout</a>
+<li><a href="poly2_r.c#furthestout">qh_furthestout</a>
make furthest outside point the last point of a
facet's outside set </li>
-<li><a href="poly.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
+<li><a href="poly_r.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
make new facets from ridges of visible facets </li>
-<li><a href="poly.c#makenew_simplicial">qh_makenew_simplicial</a>
+<li><a href="poly_r.c#makenew_simplicial">qh_makenew_simplicial</a>
make new facets for horizon neighbors </li>
-<li><a href="poly.c#makenewfacet">qh_makenewfacet</a>
+<li><a href="poly_r.c#makenewfacet">qh_makenewfacet</a>
create a facet from vertices and apex </li>
-<li><a href="poly2.c#makenewfacets">qh_makenewfacets</a>
+<li><a href="poly2_r.c#makenewfacets">qh_makenewfacets</a>
make new facets from vertex, horizon facets, and
visible facets </li>
-<li><a href="poly.c#makenewplanes">qh_makenewplanes</a>
+<li><a href="poly_r.c#makenewplanes">qh_makenewplanes</a>
make new hyperplanes for facets </li>
-<li><a href="poly2.c#outcoplanar">qh_outcoplanar</a>
+<li><a href="poly2_r.c#outcoplanar">qh_outcoplanar</a>
move points from outside set to coplanar set </li>
-<li><a href="poly2.c#setvoronoi_all">qh_setvoronoi_all</a>
+<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
compute Voronoi centers for all facets </li>
-<li><a href="poly2.c#triangulate">qh_triangulate</a>
+<li><a href="poly2_r.c#triangulate">qh_triangulate</a>
triangulate non-simplicial facets</li>
-<li><a href="poly2.c#triangulate_facet">qh_triangulate_facet</a>
+<li><a href="poly2_r.c#triangulate_facet">qh_triangulate_facet</a>
triangulate a non-simplicial facet</li>
-<li><a href="poly2.c#triangulate_link">qh_triangulate_link</a>
+<li><a href="poly2_r.c#triangulate_link">qh_triangulate_link</a>
link facets together from qh_triangulate</li>
-<li><a href="poly2.c#triangulate_mirror">qh_triangulate_mirror</a>
+<li><a href="poly2_r.c#triangulate_mirror">qh_triangulate_mirror</a>
delete mirrored facets from qh_triangulate</li>
-<li><a href="poly2.c#triangulate_null">qh_triangulate_null</a>
+<li><a href="poly2_r.c#triangulate_null">qh_triangulate_null</a>
delete null facet from qh_triangulate</li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pvertex">Vertex,
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pvertex">Vertex,
ridge, and point functions</a></h3>
<ul>
-<li><a href="poly.c#appendvertex">qh_appendvertex</a>
+<li><a href="poly_r.c#appendvertex">qh_appendvertex</a>
append vertex to end of qh.vertex_list, </li>
-<li><a href="io.c#detvridge">qh_detvridge</a> determine Voronoi
+<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
ridge for an input site
-<li><a href="io.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
+<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
ridge for an input site
-<li><a href="poly2.c#facet3vertex">qh_facet3vertex</a>
+<li><a href="poly2_r.c#facet3vertex">qh_facet3vertex</a>
return an oriented vertex set for a 3-d facet </li>
-<li><a href="poly.c#facetintersect">qh_facetintersect</a>
+<li><a href="poly_r.c#facetintersect">qh_facetintersect</a>
return intersection of simplicial facets </li>
-<li><a href="poly2.c#initialvertices">qh_initialvertices</a>
+<li><a href="poly2_r.c#initialvertices">qh_initialvertices</a>
return non-singular set of initial vertices </li>
-<li><a href="poly2.c#isvertex">qh_isvertex</a> true
+<li><a href="poly2_r.c#isvertex">qh_isvertex</a> true
if point is in a vertex set </li>
-<li><a href="poly2.c#nearvertex">qh_nearvertex</a>
+<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
return nearest vertex to point </li>
-<li><a href="poly2.c#nextridge3d">qh_nextridge3d</a>
+<li><a href="poly2_r.c#nextridge3d">qh_nextridge3d</a>
iterate over each ridge and vertex for a 3-d
facet </li>
-<li><a href="poly2.c#point">qh_point</a> return point
+<li><a href="poly2_r.c#point">qh_point</a> return point
for a point ID </li>
-<li><a href="poly2.c#pointfacet">qh_pointfacet</a>
+<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
return temporary set of facets indexed by point
ID </li>
-<li><a href="poly.c#pointid">qh_pointid</a> return ID
+<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
for a point</li>
-<li><a href="poly2.c#pointvertex">qh_pointvertex</a>
+<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
return temporary set of vertices indexed by point
ID </li>
-<li><a href="poly.c#removevertex">qh_removevertex</a>
+<li><a href="poly_r.c#removevertex">qh_removevertex</a>
unlink vertex from qh.vertex_list, </li>
-<li><a href="poly.c#updatevertices">qh_updatevertices</a>
+<li><a href="poly_r.c#updatevertices">qh_updatevertices</a>
update vertex neighbors and delete interior
vertices </li>
-<li><a href="poly2.c#vertexintersect">qh_vertexintersect</a>
+<li><a href="poly2_r.c#vertexintersect">qh_vertexintersect</a>
intersect two vertex sets </li>
-<li><a href="poly2.c#vertexintersect_new">qh_vertexintersect_new</a>
+<li><a href="poly2_r.c#vertexintersect_new">qh_vertexintersect_new</a>
return intersection of two vertex sets </li>
-<li><a href="poly2.c#vertexneighbors">qh_vertexneighbors</a>
+<li><a href="poly2_r.c#vertexneighbors">qh_vertexneighbors</a>
for each vertex in hull, determine facet
neighbors </li>
-<li><a href="poly2.c#vertexsubset">qh_vertexsubset</a>
+<li><a href="poly2_r.c#vertexsubset">qh_vertexsubset</a>
returns True if vertexsetA is a subset of
vertexsetB </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="phash">Hashtable functions</a></h3>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="phash">Hashtable functions</a></h3>
<ul>
-<li><a href="poly2.c#addhash">qh_addhash</a> add hash
+<li><a href="poly2_r.c#addhash">qh_addhash</a> add hash
element to linear hash table</li>
-<li><a href="poly.c#gethash">qh_gethash</a> return
+<li><a href="poly_r.c#gethash">qh_gethash</a> return
hash value for a set</li>
-<li><a href="poly2.c#matchduplicates">qh_matchduplicates</a>
+<li><a href="poly2_r.c#matchduplicates">qh_matchduplicates</a>
match duplicate ridges in hash table </li>
-<li><a href="poly.c#matchneighbor">qh_matchneighbor</a>
+<li><a href="poly_r.c#matchneighbor">qh_matchneighbor</a>
try to match subridge of new facet with a
neighbor </li>
-<li><a href="poly.c#matchnewfacets">qh_matchnewfacets</a>
+<li><a href="poly_r.c#matchnewfacets">qh_matchnewfacets</a>
match new facets with their new facet neighbors </li>
-<li><a href="poly.c#matchvertices">qh_matchvertices</a>
+<li><a href="poly_r.c#matchvertices">qh_matchvertices</a>
tests whether a facet and hash entry match at a
ridge </li>
-<li><a href="poly2.c#newhashtable">qh_newhashtable</a>
-allocate a new qh.hash_table </li>
-<li><a href="poly2.c#printhashtable">qh_printhashtable</a>
+<li><a href="poly2_r.c#newhashtable">qh_newhashtable</a>
+allocate a new qh_r.hash_table </li>
+<li><a href="poly2_r.c#printhashtable">qh_printhashtable</a>
print hash table </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pnew">Allocation and
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pnew">Allocation and
deallocation functions</a></h3>
<ul>
-<li><a href="poly2.c#clearcenters">qh_clearcenters</a>
+<li><a href="poly2_r.c#clearcenters">qh_clearcenters</a>
clear old data from facet-&gt;center </li>
-<li><a href="poly.c#deletevisible">qh_deletevisible</a>
+<li><a href="poly_r.c#deletevisible">qh_deletevisible</a>
delete visible facets and vertices </li>
-<li><a href="poly.c#delfacet">qh_delfacet</a> free up
+<li><a href="poly_r.c#delfacet">qh_delfacet</a> free up
the memory occupied by a facet </li>
-<li><a href="poly2.c#delridge">qh_delridge</a> delete
+<li><a href="poly2_r.c#delridge">qh_delridge</a> delete
ridge</li>
-<li><a href="poly2.c#delvertex">qh_delvertex</a>
+<li><a href="poly2_r.c#delvertex">qh_delvertex</a>
delete vertex </li>
-<li><a href="poly.c#newfacet">qh_newfacet</a> create
+<li><a href="poly_r.c#newfacet">qh_newfacet</a> create
and allocate space for a facet </li>
-<li><a href="poly.c#newridge">qh_newridge</a> create
+<li><a href="poly_r.c#newridge">qh_newridge</a> create
and allocate space for a ridge </li>
-<li><a href="poly2.c#newvertex">qh_newvertex</a>
+<li><a href="poly2_r.c#newvertex">qh_newvertex</a>
create and allocate space for a vertex </li>
</ul>
-<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pcheck">Check
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pcheck">Check
functions</a></h3>
<ul>
-<li><a href="poly2.c#check_bestdist">qh_check_bestdist</a>
+<li><a href="poly2_r.c#check_bestdist">qh_check_bestdist</a>
check that points are not outside of facets </li>
-<li><a href="poly2.c#check_maxout">qh_check_maxout</a>
+<li><a href="poly2_r.c#check_maxout">qh_check_maxout</a>
updates qh.max_outside and checks all points
against bestfacet </li>
-<li><a href="poly2.c#check_output">qh_check_output</a>
+<li><a href="poly2_r.c#check_output">qh_check_output</a>
check topological and geometric output</li>
-<li><a href="poly2.c#check_point">qh_check_point</a>
+<li><a href="poly2_r.c#check_point">qh_check_point</a>
check that point is not outside of facet </li>
-<li><a href="poly2.c#check_points">qh_check_points</a>
+<li><a href="poly2_r.c#check_points">qh_check_points</a>
check that all points are inside all facets </li>
-<li><a href="poly2.c#checkconvex">qh_checkconvex</a>
+<li><a href="poly2_r.c#checkconvex">qh_checkconvex</a>
check that each ridge in facetlist is convex </li>
-<li><a href="poly2.c#checkfacet">qh_checkfacet</a>
+<li><a href="poly2_r.c#checkfacet">qh_checkfacet</a>
check for consistency errors in facet </li>
-<li><a href="poly.c#checkflipped">qh_checkflipped</a>
+<li><a href="poly_r.c#checkflipped">qh_checkflipped</a>
check facet orientation to the interior point </li>
-<li><a href="poly2.c#checkflipped_all">qh_checkflipped_all</a>
+<li><a href="poly2_r.c#checkflipped_all">qh_checkflipped_all</a>
check facet orientation for a facet list </li>
-<li><a href="poly2.c#checkpolygon">qh_checkpolygon</a>
+<li><a href="poly2_r.c#checkpolygon">qh_checkpolygon</a>
check topological structure </li>
-<li><a href="poly2.c#checkvertex">qh_checkvertex</a>
+<li><a href="poly2_r.c#checkvertex">qh_checkvertex</a>
check vertex for consistency </li>
-<li><a href="poly2.c#infiniteloop">qh_infiniteloop</a>
+<li><a href="poly2_r.c#infiniteloop">qh_infiniteloop</a>
report error for a loop of facets </li>
-<li><a href="poly2.c#printlists">qh_printlists</a>
+<li><a href="poly2_r.c#printlists">qh_printlists</a>
print out facet list for debugging </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhull_r/qh-qhull_r.htm b/src/libqhull_r/qh-qhull_r.htm
new file mode 100644
index 0000000..16881fd
--- /dev/null
+++ b/src/libqhull_r/qh-qhull_r.htm
@@ -0,0 +1,277 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>libqhull_r_r.c -- top-level functions and basic data types</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>libqhull_r_r.c -- top-level functions and basic data types</h2>
+<blockquote>
+<p>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
+<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
+<p>This section provides an index to the top-level
+functions and base data types. The top-level header file, <tt>libqhull_r.h</tt>,
+contains prototypes for these functions.</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <b>Qhull</b> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="libqhull_r_r.c">libqhull_r_r.c</a>,
+<a href="libqhull_r.h">libqhull_r.h</a>, and
+<a href="../qhull/unix_r_r.c">unix_r_r.c</a></h3>
+<ul>
+<li><a href="#qtype">libqhull_r.h and unix_r_r.c data types and
+constants</a> </li>
+<li><a href="#qmacro">libqhull_r.h other macros</a> </li>
+<li><a href="#qfunc">Quickhull routines in call order</a> </li>
+<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
+<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
+<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
+<li><a href="#qout">Top-level routines for returning results</a></li>
+<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qtype">libqhull_r.h and unix_r_r.c
+data types and constants</a></h3>
+<ul>
+<li><a href="libqhull_r.h#flagT">flagT</a> Boolean flag as
+a bit </li>
+<li><a href="libqhull_r.h#boolT">boolT</a> boolean value,
+either True or False </li>
+<li><a href="libqhull_r.h#CENTERtype">CENTERtype</a> to
+distinguish facet-&gt;center </li>
+<li><a href="libqhull_r.h#qh_PRINT">qh_PRINT</a> output
+formats for printing (qh.PRINTout) </li>
+<li><a href="libqhull_r.h#qh_ALL">qh_ALL</a> argument flag
+for selecting everything </li>
+<li><a href="libqhull_r.h#qh_ERR">qh_ERR</a> Qhull exit
+codes for indicating errors </li>
+<li><a href="libqhull_r.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
+to distinguish error output from normal output [C++ only]</li>
+<li><a href="../qhull/unix_r_r.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
+<li><a href="../qhull/unix_r_r.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
+<li><a href="../qhull/unix_r_r.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
+<li><a href="global_r_r.c#qh_version">qh_version</a> version stamp</li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qmacro">libqhull_r.h other
+macros</a></h3>
+<ul>
+<li><a href="qhull_a_r.h#traceN">traceN</a> print trace
+message if <em>qh.IStracing &gt;= N</em>. </li>
+<li><a href="qhull_a_r.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
+ unused variable to avoid warnings. </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qfunc">Quickhull
+routines in call order</a></h3>
+<ul>
+<li><a href="../qhull/unix_r_r.c#main">main</a> processes the
+command line, calls qhull() to do the work, and
+exits </li>
+<li><a href="libqhull_r_r.c#qhull">qh_qhull</a> construct
+the convex hull of a set of points </li>
+<li><a href="libqhull_r_r.c#build_withrestart">qh_build_withrestart</a>
+allow restarts while calling qh_buildhull</li>
+<li><a href="poly2_r_r.c#initbuild">qh_initbuild</a>
+initialize hull and outside sets with point array</li>
+<li><a href="libqhull_r_r.c#partitionall">qh_partitionall</a>
+partition all points into outside sets </li>
+<li><a href="libqhull_r_r.c#buildhull">qh_buildhull</a>
+construct a convex hull by adding points one at a
+time </li>
+<li><a href="libqhull_r_r.c#nextfurthest">qh_nextfurthest</a>
+return next furthest point for processing </li>
+<li><a href="libqhull_r_r.c#buildtracing">qh_buildtracing</a>
+trace an iteration of buildhull </li>
+<li><a href="libqhull_r_r.c#addpoint">qh_addpoint</a> add a
+point to the convex hull </li>
+<li><a href="libqhull_r_r.c#findhorizon">qh_findhorizon</a>
+find the horizon and visible facets for a point </li>
+<li><a href="libqhull_r_r.c#partitionvisible">qh_partitionvisible</a>
+partition points from facets in qh.visible_list
+to facets in qh.newfacet_list </li>
+<li><a href="libqhull_r_r.c#partitionpoint">qh_partitionpoint</a>
+partition a point as inside, coplanar with, or
+outside a facet </li>
+<li><a href="libqhull_r_r.c#partitioncoplanar">qh_partitioncoplanar</a>
+partition coplanar point into a facet </li>
+<li><a href="libqhull_r_r.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
+<ul>
+<li><a href="global_r_r.c#freebuild">qh_freebuild</a>
+free memory used by qh_initbuild and qh_buildhull
+</li>
+<li><a href="global_r_r.c#checkflags">qh_checkflags</a>
+check flags for multiple frontends to qhull
+<li><a href="global_r_r.c#freeqhull">qh_freeqhull</a>
+free memory used by qhull </li>
+<li><a href="global_r_r.c#init_A">qh_init_A</a> called
+before error handling initialized </li>
+<li><a href="global_r_r.c#init_B">qh_init_B</a> called
+after points are defined </li>
+<li><a href="global_r_r.c#initflags">qh_initflags</a> set
+flags and constants from command line </li>
+<li><a href="rboxlib_r_r.c#rboxpoints">qh_rboxpoints</a>
+generate points for qhull </li>
+<li><a href="global_r_r.c#restore_qhull">qh_restore_qhull</a>
+restores a saved qhull </li>
+<li><a href="global_r_r.c#save_qhull">qh_save_qhull</a>
+saves qhull for later restoring </li>
+<li><a href="user_r_r.c#user_memsizes">qh_user_memsizes</a>
+define additional quick allocation sizes
+</li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
+<ul>
+<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
+implements Gram-Schmidt orthogonalization by rows </li>
+<li><a href="geom2_r.c#projectinput">qh_projectinput</a>
+project input along one or more dimensions +
+Delaunay projection </li>
+<li><a href="geom2_r.c#randommatrix">qh_randommatrix</a>
+generate a random dimXdim matrix in range (-1,1) </li>
+<li><a href="io_r.c#readpoints">qh_readpoints</a> read
+points from input </li>
+<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
+input points using row matrix </li>
+<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
+input points using qh low_bound/high_bound </li>
+<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
+points to paraboloid for Delaunay triangulation </li>
+<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
+generate dual for halfspace intersection with interior
+point </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
+<ul>
+<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add
+point to convex hull </li>
+<li><a href="poly2_r.c#findbestfacet">qh_findbestfacet</a>
+find facet that is furthest below a point </li>
+<li><a href="poly2_r.c#findfacet_all">qh_findfacet_all</a>
+exhaustive search for facet below a point </li>
+<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
+the convex hull of a set of points </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
+<ul>
+<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
+collect statistics for qh.facet_list </li>
+<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
+return nearest vertex to point </li>
+<li><a href="poly2_r.c#point">qh_point</a> return point
+for a point ID </li>
+<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
+return temporary set of facets indexed by point
+ID </li>
+<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
+for a point</li>
+<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
+return vertices (if any) for all points</li>
+<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
+print all statistics </li>
+<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
+print neighborhood of one or two facets </li>
+<li><a href="libqhull_r.c#printsummary">qh_printsummary</a>
+print summary </li>
+<li><a href="io_r.c#produce_output">qh_produce_output</a>
+print the results of qh_qhull() </li>
+<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
+compute Voronoi centers for all facets </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
+<ul>
+<li><a href="io_r.c#dfacet">dfacet</a> print facet by
+ID from debugger </li>
+<li><a href="io_r.c#dvertex">dvertex</a> print vertex
+by ID from debugger </li>
+<li><a href="poly2_r.c#check_output">qh_check_output</a>
+check output </li>
+<li><a href="poly2_r.c#check_points">qh_check_points</a>
+verify that all points are inside the convex hull
+</li>
+<li><a href="user_r.c#errexit">qh_errexit</a> report
+error with a facet and a ridge</li>
+<li><a href="libqhull_r.c#errexit2">qh_errexit2</a> report
+error with two facets </li>
+<li><a href="user_r.c#errprint">qh_errprint</a> print
+erroneous facets, ridge, and vertex </li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print all fields for a list of facets </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/src/libqhullr/qh-set.htm b/src/libqhull_r/qh-set_r.htm
similarity index 53%
rename from src/libqhullr/qh-set.htm
rename to src/libqhull_r/qh-set_r.htm
index e07a610..8941739 100644
--- a/src/libqhullr/qh-set.htm
+++ b/src/libqhull_r/qh-set_r.htm
@@ -1,306 +1,306 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
-<title>qset.c -- set data type and operations</title>
+<title>qset_r.c -- set data type and operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
-<h2>qset.c -- set data type and operations</h2>
+<h2>qset_r.c -- set data type and operations</h2>
<blockquote>
<p>Qhull's data structures are constructed from sets. The
-functions and macros in qset.c construct, iterate, and
+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. </p>
<p>In Qhull, a <i>set</i> is represented by an unordered
array of pointers with a maximum size and a NULL
-terminator (<a href="qset.h#setT">setT</a>).
+terminator (<a href="qset_r.h#setT">setT</a>).
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. </p>
<p>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'. </p>
<p>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. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
-<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
-<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <b>Set</b>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
+<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <b>Set</b>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
-<h3>Index to <a href="qset.c">qset.c</a> and
-<a href="qset.h">qset.h</a></h3>
+<h3>Index to <a href="qset_r.c">qset_r.c</a> and
+<a href="qset_r.h">qset_r.h</a></h3>
<ul>
<li><a href="#stype">Data types and constants</a> </li>
<li><a href="#seach">FOREACH macros</a> </li>
<li><a href="#saccess">access and size macros</a> </li>
<li><a href="#sint">internal macros</a> </li>
<li><a href="#saddr">address macros</a><p>&nbsp;</li>
<li><a href="#snew">Allocation and deallocation functions</a> </li>
<li><a href="#spred">Access and predicate functions</a>
</li>
<li><a href="#sadd">Add functions</a> </li>
<li><a href="#scheck">Check and print functions</a></li>
<li><a href="#scopy">Copy, compact, and zero functions</a></li>
<li><a href="#sdel">Delete functions</a> </li>
<li><a href="#stemp">Temporary set functions</a> </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="stype">Data types and
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="stype">Data types and
constants</a></h3>
<ul>
-<li><a href="qset.h#SETelemsize">SETelemsize</a> size
+<li><a href="qset_r.h#SETelemsize">SETelemsize</a> size
of a set element in bytes </li>
-<li><a href="qset.h#setT">setT</a> a set with a
+<li><a href="qset_r.h#setT">setT</a> a set with a
maximum size and a current size</li>
-<li><a href="libqhull.h#qh-set">qh global sets</a>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a>
global sets for temporary sets, etc. </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="seach">FOREACH macros</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="seach">FOREACH macros</a></h3>
<ul>
-<li><a href="qset.h#FOREACHelem_">FOREACHelem_</a>
+<li><a href="qset_r.h#FOREACHelem_">FOREACHelem_</a>
assign 'elem' to each element in a set </li>
-<li><a href="qset.h#FOREACHset_">FOREACHset_</a>
+<li><a href="qset_r.h#FOREACHset_">FOREACHset_</a>
assign 'set' to each set in a set of sets </li>
-<li><a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+<li><a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
define a FOREACH iterator </li>
-<li><a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+<li><a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
define an indexed FOREACH iterator </li>
-<li><a href="qset.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
+<li><a href="qset_r.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
define a reversed FOREACH iterator </li>
-<li><a href="qset.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
+<li><a href="qset_r.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
define a FOREACH iterator with e[1] and e[0]
reversed </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="saccess">Access and
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="saccess">Access and
size macros</a></h3>
<ul>
-<li><a href="qset.h#SETelem_">SETelem_</a> return the
+<li><a href="qset_r.h#SETelem_">SETelem_</a> return the
n'th element of set </li>
-<li><a href="qset.h#SETelemt_">SETelemt_</a> return
+<li><a href="qset_r.h#SETelemt_">SETelemt_</a> return
the n'th element of set as a type</li>
-<li><a href="qset.h#SETempty_">SETempty_</a> return
+<li><a href="qset_r.h#SETempty_">SETempty_</a> return
true (1) if set is empty </li>
-<li><a href="qset.h#SETfirst_">SETfirst_</a> return
+<li><a href="qset_r.h#SETfirst_">SETfirst_</a> return
first element of set </li>
-<li><a href="qset.h#SETfirstt_">SETfirstt_</a> return
+<li><a href="qset_r.h#SETfirstt_">SETfirstt_</a> return
first element of set as a type</li>
-<li><a href="qset.h#SETindex_">SETindex_</a> return
+<li><a href="qset_r.h#SETindex_">SETindex_</a> return
index of elem in set </li>
-<li><a href="qset.h#SETreturnsize_">SETreturnsize_</a>
-return size of a set (normally use <a href="qset.c#setsize">qh_setsize</a>) </li>
-<li><a href="qset.h#SETsecond_">SETsecond_</a> return
+<li><a href="qset_r.h#SETreturnsize_">SETreturnsize_</a>
+return size of a set (normally use <a href="qset_r.c#setsize">qh_setsize</a>) </li>
+<li><a href="qset_r.h#SETsecond_">SETsecond_</a> return
second element of set </li>
-<li><a href="qset.h#SETsecondt_">SETsecondt_</a>
+<li><a href="qset_r.h#SETsecondt_">SETsecondt_</a>
return second element of set as a type</li>
-<li><a href="qset.h#SETtruncate_">SETtruncate_</a>
+<li><a href="qset_r.h#SETtruncate_">SETtruncate_</a>
truncate set to size, i.e., qh_settruncate()</li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sint">Internal macros</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sint">Internal macros</a></h3>
<ul>
-<li><a href="qset.c#SETsizeaddr_">SETsizeaddr_</a>
+<li><a href="qset_r.c#SETsizeaddr_">SETsizeaddr_</a>
return pointer to end element of a set (indicates
current size) </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="saddr">address macros</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="saddr">address macros</a></h3>
<ul>
-<li><a href="qset.h#SETaddr_">SETaddr_</a> return
+<li><a href="qset_r.h#SETaddr_">SETaddr_</a> return
address of a set's elements </li>
-<li><a href="qset.h#SETelemaddr_">SETelemaddr_</a>
+<li><a href="qset_r.h#SETelemaddr_">SETelemaddr_</a>
return address of the n'th element of a set </li>
-<li><a href="qset.h#SETref_">SETref_</a> l.h.s. for
+<li><a href="qset_r.h#SETref_">SETref_</a> l_r.h.s. for
modifying the current element in a FOREACH
iteration </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="snew">Allocation and
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="snew">Allocation and
deallocation functions</a></h3>
<ul>
-<li><a href="qset.c#setfree">qh_setfree</a> free the
+<li><a href="qset_r.c#setfree">qh_setfree</a> free the
space occupied by a set </li>
-<li><a href="qset.c#setfree2">qh_setfree2</a> free a
+<li><a href="qset_r.c#setfree2">qh_setfree2</a> free a
set and its elements </li>
-<li><a href="qset.c#setfreelong">qh_setfreelong</a>
+<li><a href="qset_r.c#setfreelong">qh_setfreelong</a>
free a set only if it is in long memory </li>
-<li><a href="qset.c#setnew">qh_setnew</a> create a new
+<li><a href="qset_r.c#setnew">qh_setnew</a> create a new
set </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="spred">Access and
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="spred">Access and
predicate functions </a></h3>
<ul>
-<li><a href="qset.c#setendpointer">qh_setendpointer</a> return
+<li><a href="qset_r.c#setendpointer">qh_setendpointer</a> return
pointer to NULL terminator of a set</li>
-<li><a href="qset.c#setequal">qh_setequal</a> return 1
+<li><a href="qset_r.c#setequal">qh_setequal</a> return 1
if two sorted sets are equal </li>
-<li><a href="qset.c#setequal_except">qh_setequal_except</a>
+<li><a href="qset_r.c#setequal_except">qh_setequal_except</a>
return 1 if two sorted sets are equal except for
an element </li>
-<li><a href="qset.c#setequal_skip">qh_setequal_skip</a>
+<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
return 1 if two sorted sets are equal except for
a pair of skipped elements </li>
-<li><a href="qset.c#setequal_skip">qh_setequal_skip</a>
+<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
return 1 if two sorted sets are equal except for
a pair of skipped elements </li>
-<li><a href="qset.c#setin">qh_setin</a> return 1 if an
+<li><a href="qset_r.c#setin">qh_setin</a> return 1 if an
element is in a set </li>
-<li><a href="qset.c#setindex">qh_setindex</a> return
+<li><a href="qset_r.c#setindex">qh_setindex</a> return
the index of an element in a set </li>
-<li><a href="qset.c#setlast">qh_setlast</a> return
+<li><a href="qset_r.c#setlast">qh_setlast</a> return
last element of a set</li>
-<li><a href="qset.c#setsize">qh_setsize</a> returns
+<li><a href="qset_r.c#setsize">qh_setsize</a> returns
the size of a set </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sadd">Add functions</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sadd">Add functions</a></h3>
<ul>
-<li><a href="qset.c#setaddnth">qh_setaddnth</a> add a
+<li><a href="qset_r.c#setaddnth">qh_setaddnth</a> add a
element as n'th element of sorted or unsorted set
</li>
-<li><a href="qset.c#setaddsorted">qh_setaddsorted</a>
+<li><a href="qset_r.c#setaddsorted">qh_setaddsorted</a>
add an element to a sorted set </li>
-<li><a href="qset.c#setappend">qh_setappend</a> append
+<li><a href="qset_r.c#setappend">qh_setappend</a> append
an element to a set </li>
-<li><a href="qset.c#setappend_set">qh_setappend_set</a>
+<li><a href="qset_r.c#setappend_set">qh_setappend_set</a>
append a set of elements to a set </li>
-<li><a href="qset.c#setappend2ndlast">qh_setappend2ndlast</a>
+<li><a href="qset_r.c#setappend2ndlast">qh_setappend2ndlast</a>
add an element as the next to the last element in
a set </li>
-<li><a href="qset.c#setlarger">qh_setlarger</a> return
+<li><a href="qset_r.c#setlarger">qh_setlarger</a> return
a larger set with the same elements</li>
-<li><a href="qset.c#setreplace">qh_setreplace</a>
+<li><a href="qset_r.c#setreplace">qh_setreplace</a>
replace one element with another in a set</li>
-<li><a href="qset.c#setunique">qh_setunique</a> add an
+<li><a href="qset_r.c#setunique">qh_setunique</a> add an
element if it is not already in a set </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="scheck">Check and print functions</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="scheck">Check and print functions</a></h3>
<ul>
-<li><a href="qset.c#setcheck">qh_setcheck</a> check a
+<li><a href="qset_r.c#setcheck">qh_setcheck</a> check a
set for validity </li>
-<li><a href="qset.c#setprint">qh_setprint</a> print a
+<li><a href="qset_r.c#setprint">qh_setprint</a> print a
set's elements to fp </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="scopy">Copy, compact, and zero functions</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="scopy">Copy, compact, and zero functions</a></h3>
<ul>
-<li><a href="qset.c#setcompact">qh_setcompact</a>
+<li><a href="qset_r.c#setcompact">qh_setcompact</a>
compact NULLs from an unsorted set </li>
-<li><a href="qset.c#setcopy">qh_setcopy</a> make a
+<li><a href="qset_r.c#setcopy">qh_setcopy</a> make a
copy of a sorted or unsorted set </li>
-<li><a href="qset.c#setduplicate">qh_setduplicate</a>
+<li><a href="qset_r.c#setduplicate">qh_setduplicate</a>
duplicate a set and its elements </li>
-<li><a href="qset.c#settruncate">qh_settruncate</a>
+<li><a href="qset_r.c#settruncate">qh_settruncate</a>
truncate a set to size elements </li>
-<li><a href="qset.c#setzero">qh_setzero</a> zero the
+<li><a href="qset_r.c#setzero">qh_setzero</a> zero the
remainder of a set </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sdel">Delete functions</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sdel">Delete functions</a></h3>
<ul>
-<li><a href="qset.c#setdel">qh_setdel</a> delete an
+<li><a href="qset_r.c#setdel">qh_setdel</a> delete an
element from an unsorted set. </li>
-<li><a href="qset.c#setdellast">qh_setdellast</a>
+<li><a href="qset_r.c#setdellast">qh_setdellast</a>
delete and return last element from a set</li>
-<li><a href="qset.c#setdelnth">qh_setdelnth</a> delete
+<li><a href="qset_r.c#setdelnth">qh_setdelnth</a> delete
and return nth element from an unsorted set </li>
-<li><a href="qset.c#setdelnthsorted">qh_setdelnthsorted</a>
+<li><a href="qset_r.c#setdelnthsorted">qh_setdelnthsorted</a>
delete and return nth element from a sorted set </li>
-<li><a href="qset.c#setdelsorted">qh_setdelsorted</a>
+<li><a href="qset_r.c#setdelsorted">qh_setdelsorted</a>
delete an element from a sorted set </li>
-<li><a href="qset.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
+<li><a href="qset_r.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
create a sorted set not containing the nth
element </li>
</ul>
-<h3><a href="qh-set.htm#TOC">&#187;</a><a name="stemp">Temporary set functions</a></h3>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="stemp">Temporary set functions</a></h3>
<ul>
-<li><a href="qset.c#settemp">qh_settemp</a> return a
+<li><a href="qset_r.c#settemp">qh_settemp</a> return a
temporary set and append it qhmem.tempstack</li>
-<li><a href="qset.c#settempfree">qh_settempfree</a>
+<li><a href="qset_r.c#settempfree">qh_settempfree</a>
free and pop a set from qhmem.tempstack</li>
-<li><a href="qset.c#settempfree_all">qh_settempfree_all</a>
+<li><a href="qset_r.c#settempfree_all">qh_settempfree_all</a>
free all sets in qhmem.tempstack </li>
-<li><a href="qset.c#settemppop">qh_settemppop</a> pop
+<li><a href="qset_r.c#settemppop">qh_settemppop</a> pop
a set from qhmem.tempstack (makes it permanent) </li>
-<li><a href="qset.c#settemppush">qh_settemppush</a>
+<li><a href="qset_r.c#settemppush">qh_settemppush</a>
push a set unto qhmem.tempstack (makes it
temporary) </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhullr/qh-stat.htm b/src/libqhull_r/qh-stat_r.htm
similarity index 51%
rename from src/libqhullr/qh-stat.htm
rename to src/libqhull_r/qh-stat_r.htm
index 90bc791..d4b41db 100644
--- a/src/libqhullr/qh-stat.htm
+++ b/src/libqhull_r/qh-stat_r.htm
@@ -1,161 +1,161 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
-<title>stat.c -- statistical operations</title>
+<title>stat_r.c -- statistical operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm">User</a>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
-<h2>stat.c -- statistical operations</h2>
+<h2>stat_r.c -- statistical operations</h2>
<blockquote>
<p>Qhull records many statistics. These functions and
macros make it inexpensive to add a statistic.
<p>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'
+may be turned off in user_r.h. If so, all but the 'zz'
statistics are ignored.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
-&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
-&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <b>Stat</b> &#149; <a href="qh-user.htm#TOC">User</a>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <b>Stat</b> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
-<h3>Index to <a href="stat.c">stat.c</a> and
-<a href="stat.h">stat.h</a></h3>
+<h3>Index to <a href="stat_r.c">stat_r.c</a> and
+<a href="stat_r.h">stat_r.h</a></h3>
<ul>
-<li><a href="#ttype">stat.h types</a> </li>
-<li><a href="#tconst">stat.h constants</a> </li>
-<li><a href="#tmacro">stat.h macros</a> </li>
-<li><a href="#tfunc">stat.c functions</a> </li>
+<li><a href="#ttype">stat_r.h types</a> </li>
+<li><a href="#tconst">stat_r.h constants</a> </li>
+<li><a href="#tmacro">stat_r.h macros</a> </li>
+<li><a href="#tfunc">stat_r.c functions</a> </li>
</ul>
-<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="ttype">stat.h types</a></h3>
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="ttype">stat_r.h types</a></h3>
<ul>
-<li><a href="stat.h#intrealT">intrealT</a> union of
+<li><a href="stat_r.h#intrealT">intrealT</a> union of
integer and real</li>
-<li><a href="stat.h#qhstat">qhstat</a> global data
+<li><a href="stat_r.h#qhstat">qhstat</a> global data
structure for statistics </li>
</ul>
-<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tconst">stat.h
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tconst">stat_r.h
constants</a></h3>
<ul>
-<li><a href="stat.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
-<li><a href="stat.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
+<li><a href="stat_r.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
+<li><a href="stat_r.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
</li>
-<li><a href="stat.h#ZZstat">ZZstat</a> Z.../W... statistics that
+<li><a href="stat_r.h#ZZstat">ZZstat</a> Z.../W... statistics that
remain defined if qh_KEEPstatistics=0
</li>
-<li><a href="stat.h#ztype">ztype</a> zdoc, zinc, etc.
+<li><a href="stat_r.h#ztype">ztype</a> zdoc, zinc, etc.
for definining statistics </li>
</ul>
-<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tmacro">stat.h macros</a></h3>
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tmacro">stat_r.h macros</a></h3>
<ul>
-<li><a href="stat.h#MAYdebugx">MAYdebugx</a> called
+<li><a href="stat_r.h#MAYdebugx">MAYdebugx</a> called
frequently for error trapping </li>
-<li><a href="stat.h#zadd_">zadd_/wadd_</a> add value
+<li><a href="stat_r.h#zadd_">zadd_/wadd_</a> add value
to an integer or real statistic </li>
-<li><a href="stat.h#zdef_">zdef_</a> define a
+<li><a href="stat_r.h#zdef_">zdef_</a> define a
statistic </li>
-<li><a href="stat.h#zinc_">zinc_</a> increment an
+<li><a href="stat_r.h#zinc_">zinc_</a> increment an
integer statistic </li>
-<li><a href="stat.h#zmax_">zmax_/wmax_</a> update
+<li><a href="stat_r.h#zmax_">zmax_/wmax_</a> update
integer or real maximum statistic </li>
-<li><a href="stat.h#zmin_">zmin_/wmin_</a> update
+<li><a href="stat_r.h#zmin_">zmin_/wmin_</a> update
integer or real minimum statistic </li>
-<li><a href="stat.h#zval_">zval_/wval_</a> set or
+<li><a href="stat_r.h#zval_">zval_/wval_</a> set or
return value of a statistic </li>
</ul>
-<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tfunc">stat.c
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tfunc">stat_r.c
functions</a></h3>
<ul>
-<li><a href="stat.c#allstatA">qh_allstatA</a> define
+<li><a href="stat_r.c#allstatA">qh_allstatA</a> define
statistics in groups of 20 </li>
-<li><a href="stat.c#allstatistics">qh_allstatistics</a>
+<li><a href="stat_r.c#allstatistics">qh_allstatistics</a>
reset printed flag for all statistics </li>
-<li><a href="stat.c#collectstatistics">qh_collectstatistics</a>
+<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
collect statistics for qh.facet_list </li>
-<li><a href="stat.c#freestatistics">qh_freestatistics</a>
+<li><a href="stat_r.c#freestatistics">qh_freestatistics</a>
free memory used for statistics </li>
-<li><a href="stat.c#initstatistics">qh_initstatistics</a>
+<li><a href="stat_r.c#initstatistics">qh_initstatistics</a>
allocate and initialize statistics </li>
-<li><a href="stat.c#newstats">qh_newstats</a> returns
+<li><a href="stat_r.c#newstats">qh_newstats</a> returns
True if statistics for zdoc </li>
-<li><a href="stat.c#nostatistic">qh_nostatistic</a>
+<li><a href="stat_r.c#nostatistic">qh_nostatistic</a>
true if no statistic to print </li>
-<li><a href="stat.c#printallstatistics">qh_printallstatistics</a>
+<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
print all statistics </li>
-<li><a href="stat.c#printstatistics">qh_printstatistics</a>
+<li><a href="stat_r.c#printstatistics">qh_printstatistics</a>
print statistics to a file </li>
-<li><a href="stat.c#printstatlevel">qh_printstatlevel</a>
+<li><a href="stat_r.c#printstatlevel">qh_printstatlevel</a>
print level information for a statistic </li>
-<li><a href="stat.c#printstats">qh_printstats</a>
+<li><a href="stat_r.c#printstats">qh_printstats</a>
print statistics for a zdoc group </li>
-<li><a href="stat.c#stddev">qh_stddev</a> compute the
+<li><a href="stat_r.c#stddev">qh_stddev</a> compute the
standard deviation and average from statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>
diff --git a/src/libqhull_r/qh-user_r.htm b/src/libqhull_r/qh-user_r.htm
new file mode 100644
index 0000000..4a4f7f0
--- /dev/null
+++ b/src/libqhull_r/qh-user_r.htm
@@ -0,0 +1,265 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>user_r.c -- user-definable operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<hr>
+<h2>user_r.c -- user-definable operations</h2>
+<blockquote>
+<p>This section contains functions and constants that the
+user may want to change. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <b>User</b>
+</p>
+<h3>Index to <a href="user_r.c">user_r.c</a>, <a href="usermem_r.c">usermem_r.c</a>, <a href="userprintf_r.c">userprintf_r.c</a>, <a href="userprintf_rbox_r.c">userprintf_rbox_r.c</a> and
+<a href="user_r.h">user_r.h</a></h3>
+<ul>
+<li><a href="#qulllib">qhull library constants</a></li>
+<li><a href="#utype">user_r.h data types and
+configuration macros</a> </li>
+<li><a href="#ujoggle">joggle constants</a></li>
+<li><a href="#uperform">performance related constants</a></li>
+<li><a href="#umemory">memory constants</a></li>
+<li><a href="#ucond">conditional compilation</a></li>
+<li><a href="#umerge">merge constants</a> </li>
+<li><a href="#ufunc">user_r.c functions</a> </li>
+<li><a href="#u2func">usermem_r.c functions</a> </li>
+<li><a href="#u3func">userprintf_r.c functions</a> </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="qulllib">Qhull library constants</a></h3>
+<ul>
+<li><a href="user_r.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
+<li><a href="user_r.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
+<li><a href="user_r.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
+</ul>
+
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="utype">user_r.h data
+types and configuration macros</a></h3>
+<ul>
+<li><a href="user_r.h#realT">realT, qh_REAL...</a> size
+of floating point numbers </li>
+<li><a href="user_r.h#countT">countT, COUNTmax</a> size
+of counts and identifiers, typically 'int' or 'long long' </li>
+<li><a href="user_r.h#CPUclock">qh_CPUclock</a> clock()
+function for reporting the total time spent by
+Qhull </li>
+<li><a href="user_r.h#RANDOM">qh_RANDOM...</a> random
+number generator </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="udef">definition constants</a></h3>
+<ul>
+<li><a href="user_r.h#DEFAULTbox">qh_DEFAULTbox</a>
+define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
+<li><a href="user_r.h#INFINITE">qh_INFINITE</a> on
+output, indicates Voronoi center at infinity </li>
+<li><a href="user_r.h#ORIENTclock">qh_ORIENTclock</a>
+define convention for orienting facets</li>
+<li><a href="user_r.h#ZEROdelaunay">qh_ZEROdelaunay</a>
+define facets that are ignored in Delaunay triangulations</li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ujoggle">joggle constants</a></h3>
+<ul>
+<li><a href="user_r.h#JOGGLEagain">qh_JOGGLEagain</a>
+how often to retry before using qh_JOGGLEmaxincrease
+again </li>
+<li><a href="user_r.h#JOGGLEdefault">qh_JOGGLEdefault</a>
+default value for qh.JOGGLEmax for 'QP' </li>
+<li><a href="user_r.h#JOGGLEincrease">qh_JOGGLEincrease</a>
+factor to increase qh.JOGGLEmax on retrys for
+'QPn' </li>
+<li><a href="user_r.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
+for increasing qh.JOGGLEmax relative to
+qh.MAXwidth </li>
+<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
+report error if this many retries </li>
+<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEretry</a>
+how often to retry before using qh_JOGGLEmax </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="uperform">performance
+related constants</a></h3>
+<ul>
+<li><a href="user_r.h#HASHfactor">qh_HASHfactor</a>
+total/used hash slots </li>
+<li><a href="user_r.h#INITIALmax">qh_INITIALmax</a> if
+dim &gt;= qh_INITIALmax, use min/max coordinate
+points for initial simplex </li>
+<li><a href="user_r.h#INITIALsearch">qh_INITIALsearch</a>
+if qh.INITIALmax, search points up to this
+dimension </li>
+<li><a href="user_r.h#NOtrace">qh_NOtrace</a> disallow
+tracing </li>
+<li><a href="user_r.h#VERIFYdirect">qh_VERIFYdirect</a>
+'Tv' verifies all <em>points X facets</em> if op
+count is smaller </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="umemory">memory constants</a></h3>
+<ul>
+<li><a href="user_r.h#MEMalign">qh_MEMalign</a> memory
+alignment for qh_meminitbuffers() in global_r.c </li>
+<li><a href="user_r.h#MEMbufsize">qh_MEMbufsize</a>
+size of additional memory buffers </li>
+<li><a href="user_r.h#MEMinitbuf">qh_MEMinitbuf</a>
+size of initial memory buffer </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ucond">conditional compilation</a></h3>
+<ul>
+<li><a href="user_r.h#compiler">compiler</a> defined symbols,
+e.g., _STDC_ and _cplusplus
+
+<li><a href="user_r.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
+ compute furthest distance to an outside point instead of storing it with the facet
+<li><a href="user_r.h#KEEPstatistics">qh_KEEPstatistics</a>
+ enable statistic gathering and reporting with option 'Ts'
+<li><a href="user_r.h#MAXoutside">qh_MAXoutside</a>
+record outer plane for each facet
+<li><a href="user_r.h#NOmerge">qh_NOmerge</a>
+disable facet merging
+<li><a href="user_r.h#NOtrace">qh_NOtrace</a>
+disable tracing with option 'T4'
+<li><a href="user_r.h#QHpointer">qh_QHpointer</a>
+access global data with pointer or static structure
+<li><a href="user_r.h#QUICKhelp">qh_QUICKhelp</a>
+use abbreviated help messages, e.g., for degenerate inputs
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="umerge">merge
+constants</a></h3>
+<ul>
+<li><a href="user_r.h#BESTcentrum">qh_BESTcentrum</a>
+when does qh_findbestneighbor() test centrums? </li>
+<li><a href="user_r.h#BESTnonconvex">qh_BESTnonconvex</a>
+when does qh_findbestneighbor() test nonconvex
+ridges only? </li>
+<li><a href="user_r.h#COPLANARratio">qh_COPLANARratio</a>
+what is qh.MINvisible? </li>
+<li><a href="user_r.h#DIMreduceBuild">qh_DIMreduceBuild</a>
+max dimension for vertex reduction </li>
+<li><a href="user_r.h#DIMmergeVertex">qh_DIMmergeVertex</a>
+max dimension for vertex merging </li>
+<li><a href="user_r.h#DISToutside">qh_DISToutside</a>
+when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall</li>
+<li><a href="user_r.h#MAXnarrow">qh_MAXnarrow</a> max.
+cosine for qh.NARROWhull </li>
+<li><a href="user_r.h#MAXnewcentrum">qh_MAXnewcentrum</a>
+when does qh_reducevertices_centrum() reset the
+centrum? </li>
+<li><a href="user_r.h#MAXnewmerges">qh_MAXnewmerges</a>
+when does qh_merge_nonconvex() call
+qh_reducevertices_centrums? </li>
+<li><a href="user_r.h#RATIOnearinside">qh_RATIOnearinside</a>
+ratio for retaining inside points for
+qh_check_maxout() </li>
+<li><a href="user_r.h#SEARCHdist">qh_SEARCHdist</a>
+when is facet coplanar with the best facet for qh_findbesthorizon</li>
+<li><a href="user_r.h#USEfindbestnew">qh_USEfindbestnew</a>
+when to use qh_findbestnew for qh_partitionpoint()</li>
+<li><a href="user_r.h#WIDEcoplanar">qh_WIDEcoplanar</a>
+what is a WIDEfacet? </li>
+<li><a href="user_r.h#WARNnarrow">qh_WARNnarrow</a>
+max. cosine to warn about qh.NARROWhull </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ufunc">user_r.c
+functions</a></h3>
+<ul>
+<li><a href="user_r.c#errexit">qh_errexit</a> report
+error and exit qhull()</li>
+<li><a href="user_r.c#errprint">qh_errprint</a> print
+information about facets and ridges </li>
+<li><a href="user_r.c#new_qhull">qh_new_qhull</a> call qhull on an array
+of points</li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print all fields of all facets </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="u2func">usermem_r.c
+functions</a></h3>
+<ul>
+<li><a href="usermem_r.c#qh_exit">qh_exit</a> exit program, same as exit().</li>
+<li><a href="usermem_r.c#qh_free">qh_free</a> free memory, same as free().</li>
+<li><a href="usermem_r.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="u3func">userprintf_r.c
+ and userprintf_rbox,c functions</a></h3>
+<ul>
+<li><a href="userprintf_r.c#qh_fprintf">qh_fprintf</a> print
+information from Qhull, sames as fprintf(). </li>
+<li><a href="userprintf_rbox_r.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
+information from Rbox, sames as fprintf(). </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/src/libqhullr/qhull_r-exports.def b/src/libqhull_r/qhull_r-exports.def
similarity index 97%
rename from src/libqhullr/qhull_r-exports.def
rename to src/libqhull_r/qhull_r-exports.def
index cdc7a7d..ea95df7 100644
--- a/src/libqhullr/qhull_r-exports.def
+++ b/src/libqhull_r/qhull_r-exports.def
@@ -1,399 +1,401 @@
; 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/2011/qhull/src/libqhullr/qhull_r-exports.def#3 $$Change: 1663 $
-; $DateTime: 2014/01/19 17:59:16 $$Author: bbarber $
+; $Id: //main/2011/qhull/src/libqhull_r/qhull_r-exports.def#3 $$Change: 1951 $
+; $DateTime: 2015/08/30 21:30:30 $$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 6.3
+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_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_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_vertexintersect
qh_vertexintersect_new
qh_vertexneighbors
qh_vertexridges
qh_vertexridges_facet
qh_vertexsubset
qh_voronoi_center
qh_willdelete
+qh_zero
diff --git a/src/libqhullr/qhull_ra.h b/src/libqhull_r/qhull_ra.h
similarity index 95%
rename from src/libqhullr/qhull_ra.h
rename to src/libqhull_r/qhull_ra.h
index ce986be..7fe06b5 100644
--- a/src/libqhullr/qhull_ra.h
+++ b/src/libqhull_r/qhull_ra.h
@@ -1,151 +1,151 @@
/*<html><pre> -<a href="qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
qhull_ra.h
all header files for compiling qhull with reentrant code
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/2011/qhull/src/libqhullr/qhull_ra.h#8 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/qhull_ra.h#2 $$Change: 1914 $
+ $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
Notes: grep for ((" and (" to catch fprintf("lkasdjf");
full parens around (x?y:z)
- use '#include qhull/qhull_ra.h' to avoid name clashes
+ use '#include libqhull_r/qhull_ra.h' to avoid name clashes
*/
#ifndef qhDEFqhulla
#define qhDEFqhulla 1
#include "libqhull_r.h" /* Defines 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 <setjmp.h>
#include <string.h>
#include <math.h>
#include <float.h> /* some compilers will not need float.h */
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
/*** uncomment here and qset_r.c
if string.h does not define memcpy()
#include <memory.h>
*/
#if qh_CLOCKtype == 2 /* defined in user_r.h from libqhull_r.h */
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#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- =========== */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="traceN">-</a>
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 */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="QHULL_UNUSED">-</a>
*/
/* See Qt's qglobal.h */
#if !defined(SAG_COM) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
# define QHULL_OS_WIN
#elif defined(__MWERKS__) && defined(__INTEL__)
# define QHULL_OS_WIN
#endif
#if defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
template <typename T>
-inline void qhullUnused(T &x) { (void)x; }
+inline void qhullUnused(typename T &x) { (void)x; }
# define QHULL_UNUSED(x) qhullUnused(x);
#else
# define QHULL_UNUSED(x) (void)x;
#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);
#endif /* qhDEFqhulla */
diff --git a/src/libqhullr/qset_r.c b/src/libqhull_r/qset_r.c
similarity index 92%
rename from src/libqhullr/qset_r.c
rename to src/libqhull_r/qset_r.c
index be4ddd5..b72de1a 100644
--- a/src/libqhullr/qset_r.c
+++ b/src/libqhull_r/qset_r.c
@@ -1,1340 +1,1340 @@
-/*<html><pre> -<a href="qh-set.htm"
+/*<html><pre> -<a href="qh-set_r.htm"
>-------------------------------</a><a name="TOP">-</a>
qset_r.c
implements set manipulations needed for quickhull
- see qh-set.htm and qset_r.h
+ 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/2011/qhull/src/libqhullr/qset_r.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/qset_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qset_r.h"
#include "libqhull_r.h" /* for qhT */
#include "mem_r.h"
#include <stdio.h>
#include <string.h>
/*** uncomment here and qhull_ra.h
if string.h does not define memcpy()
#include <memory.h>
*/
#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 ===================*/
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>--------------------------------<a name="setaddnth">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>--------------------------------<a name="setaddsorted">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setappend">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setappend_set">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setappend2ndlast">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setcheck">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setcompact">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setcopy">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setdel">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setdellast">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setdelnth">-</a>
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;
elemp= (setelemT *)SETelemaddr_(set, nth, void);
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);
}
lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
elem= elemp->p;
elemp->p= lastp->p; /* may overwrite itself */
lastp->p= NULL;
return elem;
} /* setdelnth */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setdelnthsorted">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setdelsorted">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setduplicate">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setendpointer">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setequal">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setequal_except">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setequal_skip">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setfree">-</a>
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 !qh_NOmem */
+ 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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setfree2">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setfreelong">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setin">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setindex">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setlarger">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setlast">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setnew">-</a>
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 !qh_NOmem */
+ int sizereceived; /* used if !qh_NOmem */
int size;
- void **freelistp; /* used !qh_NOmem */
+ 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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setnew_delnthsorted">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setprint">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setreplace">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setsize">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="settemp">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="settempfree">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="settempfree_all">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="settemppop">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="settemppush">-</a>
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) {
fprintf (qh->qhmem.ferr, "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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="settruncate">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setunique">-</a>
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 */
-/*-<a href="qh-set.htm#TOC"
+/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="setzero">-</a>
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/libqhullr/qset_r.h b/src/libqhull_r/qset_r.h
similarity index 99%
rename from src/libqhullr/qset_r.h
rename to src/libqhull_r/qset_r.h
index 2a1556d..80fdb84 100644
--- a/src/libqhullr/qset_r.h
+++ b/src/libqhull_r/qset_r.h
@@ -1,498 +1,498 @@
/*<html><pre> -<a href="qh-set.htm"
>-------------------------------</a><a name="TOP">-</a>
qset_r.h
header file for qset_r.c that implements set
see qh-set.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/2011/qhull/src/libqhullr/qset_r.h#9 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/qset_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFset
#define qhDEFset 1
#include <stdio.h>
/*================= -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
#ifndef DEFcountT
#define DEFcountT 1
typedef int countT; /* defined in user_r.h */
#endif
/*-<a href="qh-set.htm#TOC"
>----------------------------------------</a><a name="setT">-</a>
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;
countT i; /* integer used for e[maxSize] */
};
struct setT {
countT 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- =========================*/
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="SETelemsize">-</a>
SETelemsize
size of a set element in bytes
*/
#define SETelemsize ((int)sizeof(setelemT))
/*=========== -macros- =========================*/
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHsetelement_">-</a>
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++);)
/*-<a href="qh-set.htm#TOC"
>----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
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) )
/*-<a href="qh-set.htm#TOC"
>--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
FOREACHsetelementreverse_(qh, type, set, variable)-
define FOREACH iterator in reverse order
declare:
assumes *variable and **variablep are declared
also declare 'countT 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))
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
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++))
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHelem_">-</a>
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)
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHset_">-</a>
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)
/*-<a href="qh-set.htm#TOC"
>-----------------------------------------</a><a name="SETindex_">-</a>
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) ((countT)((void **)elem##p - (void **)&(set)->e[1].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETref_">-</a>
SETref_( elem )
l.h.s. for modifying the current element in a FOREACH iteration
example:
SETref_(ridge)= anotherridge;
*/
#define SETref_(elem) (elem##p[-1])
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETelem_">-</a>
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)
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETelemt_">-</a>
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))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETelemaddr_">-</a>
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)))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETfirst_">-</a>
SETfirst_(set)
return first element of set
*/
#define SETfirst_(set) ((set)->e[0].p)
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETfirstt_">-</a>
SETfirstt_(set, type)
return first element of set as a type
*/
#define SETfirstt_(set, type) ((type*)((set)->e[0].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETsecond_">-</a>
SETsecond_(set)
return second element of set
*/
#define SETsecond_(set) ((set)->e[1].p)
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETsecondt_">-</a>
SETsecondt_(set, type)
return second element of set as a type
*/
#define SETsecondt_(set, type) ((type*)((set)->e[1].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETaddr_">-</a>
SETaddr_(set, type)
return address of set's elements
*/
#define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETreturnsize_">-</a>
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))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETempty_">-</a>
SETempty_(set)
return true(1) if set is empty
notes:
set may be NULL
*/
#define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="SETsizeaddr_">-</a>
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]))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETtruncate_">-</a>
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(qhT *qh, setT **setp, void *elem);
void qh_setaddnth(qhT *qh, setT **setp, countT 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, countT extra);
void *qh_setdel(setT *set, void *elem);
void *qh_setdellast(setT *set);
void *qh_setdelnth(qhT *qh, setT *set, countT nth);
void *qh_setdelnthsorted(qhT *qh, setT *set, countT 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);
countT qh_setindex(setT *set, void *setelem);
void qh_setlarger(qhT *qh, setT **setp);
void *qh_setlast(setT *set);
setT *qh_setnew(qhT *qh, countT size);
setT *qh_setnew_delnthsorted(qhT *qh, setT *set, countT size, countT nth, countT prepend);
void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set);
void qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem);
countT qh_setsize(qhT *qh, setT *set);
setT *qh_settemp(qhT *qh, countT 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, countT size);
int qh_setunique(qhT *qh, setT **set, void *elem);
void qh_setzero(qhT *qh, setT *set, countT idx, countT size);
#endif /* qhDEFset */
diff --git a/src/libqhullr/random_r.c b/src/libqhull_r/random_r.c
similarity index 94%
rename from src/libqhullr/random_r.c
rename to src/libqhull_r/random_r.c
index c35702b..191f073 100644
--- a/src/libqhullr/random_r.c
+++ b/src/libqhull_r/random_r.c
@@ -1,245 +1,247 @@
/*<html><pre> -<a href="index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
random_r.c -- utilities
Park & Miller's minimimal standard random number generator
argc/argv conversion
Used by rbox_r.c Do not use 'qh'
*/
#include "libqhull_r.h"
+#include "random_r.h"
+
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#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
-/*-<a href="qh-globa.htm#TOC"
+/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="argv_to_command">-</a>
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 */
-/*-<a href="qh-globa.htm#TOC"
+/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="argv_to_command_size">-</a>
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; i<argc; i++){
count += (int)strlen(argv[i]) + 1; /* WARN64 */
if (i>0 && strchr(argv[i], ' ')) {
count += 2; /* quote delimiters */
for (s=argv[i]; *s; s++) {
if (*s == '"') {
count++;
}
}
}
}
return count;
} /* argv_to_command_size */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="rand">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="randomfactor">-</a>
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 */
-/*-<a href="qh-geom.htm#TOC"
+/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="randommatrix">-</a>
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 */
-/*-<a href="qh-globa.htm#TOC"
+/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="strtol">-</a>
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/libqhullr/random_r.h b/src/libqhull_r/random_r.h
similarity index 87%
rename from src/libqhullr/random_r.h
rename to src/libqhull_r/random_r.h
index f5ee920..c4bf61c 100644
--- a/src/libqhullr/random_r.h
+++ b/src/libqhull_r/random_r.h
@@ -1,34 +1,34 @@
/*<html><pre> -<a href="qh-geom.htm"
>-------------------------------</a><a name="TOP">-</a>
random.h
header file for random routines
see qh-geom.htm and random_r.c
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/random_r.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/random_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$Author: bbarber $
*/
#ifndef qhDEFrandom
#define qhDEFrandom 1
#include "libqhull_r.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(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);
#endif /* qhDEFrandom */
diff --git a/src/libqhullr/rboxlib_r.c b/src/libqhull_r/rboxlib_r.c
similarity index 98%
rename from src/libqhullr/rboxlib_r.c
rename to src/libqhull_r/rboxlib_r.c
index ec84adf..832472c 100644
--- a/src/libqhullr/rboxlib_r.c
+++ b/src/libqhull_r/rboxlib_r.c
@@ -1,771 +1,772 @@
/*<html><pre> -<a href="index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
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 "random_r.h"
#include "libqhull_r.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <setjmp.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#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_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);
-/*-<a href="qh-qhull.htm#TOC"
+/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="rboxpoints">-</a>
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.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 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;
double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
double *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 */
+ /* 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 '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);
}
/* ============= 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;
/* ============= 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; i<dim; i++) {
for (k=0; k<dim; k++)
*(simplexp++)= i==k ? 1.0 : 0.0;
}
for (k=0; k<dim; k++)
*(simplexp++)= -1.0;
}else {
for (i=0; i<dim+1; i++) {
for (k=0; k<dim; k++) {
randr= qh_RANDOMint;
*(simplexp++)= 2.0 * randr/randmax - 1.0;
}
}
}
if (issimplex2) {
simplexp= simplex;
for (i=0; i<dim+1; i++) {
if (iscdd)
qh_out1(qh, 1.0);
for (k=0; k<dim; k++)
qh_out1(qh, *(simplexp++) * box);
qh_fprintf_rbox(qh, qh->fout, 9395, "\n");
}
}
for (j=0; j<numpoints; j++) {
if (iswidth)
apex= qh_RANDOMint % (dim+1);
else
apex= -1;
for (k=0; k<dim; k++)
coord[k]= 0.0;
norm= 0.0;
for (i=0; i<dim+1; i++) {
randr= qh_RANDOMint;
factor= randr/randmax;
if (i == apex)
factor *= width;
norm += factor;
for (k=0; k<dim; k++) {
simplexp= simplex + i*dim + k;
coord[k] += factor * (*simplexp);
}
}
for (k=0; k<dim; k++)
coord[k] /= norm;
if (iscdd)
qh_out1(qh, 1.0);
for (k=0; k < dim; k++)
qh_out1(qh, coord[k] * box);
qh_fprintf_rbox(qh, qh->fout, 9396, "\n");
}
isregular= 0; /* continue with isbox */
numpoints= 0;
}
/* ============= mesh distribution =============== */
if (ismesh) {
nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
for (k=dim; k--; )
mult[k]= 0;
for (i=0; i < numpoints; i++) {
for (k=0; k < dim; k++) {
if (k == 0)
qh_out1(qh, mult[0] * meshn + mult[1] * (-meshm));
else if (k == 1)
qh_out1(qh, mult[0] * meshm + mult[1] * meshn);
else
qh_out1(qh, mult[k] * meshr );
}
qh_fprintf_rbox(qh, qh->fout, 9397, "\n");
for (k=0; k < dim; k++) {
if (++mult[k] < nthroot)
break;
mult[k]= 0;
}
}
}
/* ============= regular points for 's' =============== */
else if (isregular && !islens) {
if (dim != 2 && dim != 3) {
qh_fprintf_rbox(qh, qh->ferr, 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_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; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln s' distribution =========== */
}else if (islens && issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
randr= qh_RANDOMint;
rangap= 1.0 - gap * randr/randmax;
factor= rangap / norm;
for (j=0; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln' distribution ========== */
}else if (islens && !issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * gap;
else
coord[j]= 1.0 - coord[j] * gap;
/* ============= point of 'l' distribution =============== */
}else if (isspiral) {
if (dim != 3) {
qh_fprintf_rbox(qh, qh->ferr, 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<dim; j++)
coord[j]= factor * coord[j];
}
/* ============= project 'Zn s' point in to sphere =============== */
if (isaxis && issphere) {
coord[dim-1]= 1.0;
norm= 1.0;
for (j=0; j<gendim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] / norm;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
/* ============= project 'Zn' point onto cube =============== */
}else if (isaxis && !issphere) { /* not very interesting */
randr= qh_RANDOMint;
coord[dim-1]= 2.0 * randr/randmax - 1.0;
/* ============= project 'Ln' point out to sphere =============== */
}else if (islens) {
coord[dim-1]= lensbase;
for (j=0, norm= 0; j<dim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] * radius/ norm;
coord[dim-1] -= lensbase;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
if (qh_RANDOMint > randmax/2)
coord[dim-1]= -coord[dim-1];
/* ============= project 'Wn' point toward boundary =============== */
}else if (iswidth && !issphere) {
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * width;
else
coord[j]= 1.0 - coord[j] * width;
}
/* ============= write point =============== */
if (iscdd)
qh_out1(qh, 1.0);
for (k=0; k < dim; k++)
qh_out1(qh, coord[k] * box);
qh_fprintf_rbox(qh, qh->fout, 9399, "\n");
}
}
/* ============= write cube vertices =============== */
if (addcube) {
for (j=0; j<cubesize; j++) {
if (iscdd)
qh_out1(qh, 1.0);
for (k=dim-1; 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<diamondsize; j++) {
if (iscdd)
qh_out1(qh, 1.0);
for (k=dim-1; k>=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 */
if (simplex)
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 */
/*------------------------------------------------
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/libqhullr/stat_r.c b/src/libqhull_r/stat_r.c
similarity index 96%
rename from src/libqhullr/stat_r.c
rename to src/libqhull_r/stat_r.c
index 7ffb072..f66549e 100644
--- a/src/libqhullr/stat_r.c
+++ b/src/libqhull_r/stat_r.c
@@ -1,683 +1,682 @@
-/*<html><pre> -<a href="qh-stat.htm"
+/*<html><pre> -<a href="qh-stat_r.htm"
>-------------------------------</a><a name="TOP">-</a>
stat_r.c
contains all statistics that are collected for qhull
- see qh-stat.htm and stat_r.h
+ see qh-stat_r.htm and stat_r.h
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/stat_r.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/stat_r.c#2 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*========== functions in alphabetic order ================*/
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="allstatA">-</a>
qh_allstatA()
define statistics in groups of 20
notes:
(otherwise, 'gcc -O2' uses too much memory)
- uses qhstat.next
+ 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_(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 and outside and coplanar 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 */
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="allstatistics">-</a>
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
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="collectstatistics">-</a>
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) + sizeof(qhstatT);
+ 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 */
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="initstatistics">-</a>
qh_initstatistics(qh)
initialize statistics
Requires
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.
+ 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 */
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="newstats">-</a>
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 */
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="nostatistic">-</a>
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
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printallstatistics">-</a>
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);
}
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printstatistics">-</a>
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 */
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printstatlevel">-</a>
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, int start) {
#define NULLfield " "
+ QHULL_UNUSED(start)
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;
}
- start= 0; /* not used */
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 */
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printstats">-</a>
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; j<nexti; j++)
qh_printstatlevel(qh, fp, qh->qhstat.id[j], 0);
}
if (nextindex)
*nextindex= nexti;
} /* printstats */
#if qh_KEEPstatistics
-/*-<a href="qh-stat.htm#TOC"
+/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="stddev">-</a>
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/libqhullr/stat_r.h b/src/libqhull_r/stat_r.h
similarity index 99%
rename from src/libqhullr/stat_r.h
rename to src/libqhull_r/stat_r.h
index 74d91ff..acfcc4a 100644
--- a/src/libqhullr/stat_r.h
+++ b/src/libqhull_r/stat_r.h
@@ -1,523 +1,523 @@
/*<html><pre> -<a href="qh-stat.htm"
>-------------------------------</a><a name="TOP">-</a>
stat_r.h
contains all statistics that are collected for qhull
see qh-stat.htm and stat_r.c
Copyright (c) 1993-2015 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhullr/stat_r.h#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/libqhull_r/stat_r.h#1 $$Change: 1905 $
+ $DateTime: 2015/06/21 12:05:06 $$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
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
*/
#ifndef qh_KEEPstatistics
#define qh_KEEPstatistics 1
#endif
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="statistics">-</a>
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">-</a>
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,
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};
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="ZZstat">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="ztype">-</a>
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 =============*/
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="MAYdebugx">-</a>
MAYdebugx
define as maydebug() to be called frequently for error trapping
*/
#define MAYdebugx
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zdef_">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zinc_">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zadd_">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zval_">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zmax_">-</a>
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
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zmin_">-</a>
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 ==============*/
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="intrealT">-</a>
intrealT
union of integer and real, used for statistics
*/
typedef union intrealT intrealT; /* union of int and realT */
union intrealT {
int i;
realT r;
};
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="qhstat">-</a>
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 ===========*/
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, int start);
void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex);
realT qh_stddev(int num, realT tot, realT tot2, realT *ave);
#endif /* qhDEFstat */
diff --git a/src/libqhullr/user_r.c b/src/libqhull_r/user_r.c
similarity index 94%
rename from src/libqhullr/user_r.c
rename to src/libqhull_r/user_r.c
index 85c5cab..dda1711 100644
--- a/src/libqhullr/user_r.c
+++ b/src/libqhull_r/user_r.c
@@ -1,513 +1,524 @@
-/*<html><pre> -<a href="qh-user.htm"
+/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
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_r.c, unix_r.c, and qhull_interface.cpp 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
call_qhull is a template for calling qhull from within your application
if you recompile and load this module, then user.o will not be loaded
from qhull.a
you can add additional quick allocation sizes in qh_user_memsizes
if the other functions here are redefined to not use qh_print...,
then io.o will not be loaded from qhull.a. See user_eg_r.c for an
example. We recommend keeping io.o for the extra debugging
information it supplies.
*/
#include "qhull_ra.h"
#include <stdarg.h>
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="call_qhull">-</a>
qh_call_qhull(qh, void )
template for calling qhull from inside your program
remove #if 0, #endif to compile
returns:
exit code(see qh_ERR... in libqhull_r.h)
all memory freed
notes:
This can be called any number of times.
see:
qh_call_qhull_once()
*/
#if 0
{
int dim; /* dimension of points */
int numpoints; /* number of points */
coordT *points; /* array of coordinates for each point */
boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
FILE *outfile= stdout; /* output from qh_produce_output(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
+
+ 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
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="new_qhull">-</a>
qh_new_qhull(qh, dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
- build new qhull data structure and return exitcode (0 if no errors)
+ 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)
- outfile may be null
+ errfile must be defined, 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:
user_eg.c for an example
*/
int qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
char *qhull_cmd, FILE *outfile, FILE *errfile) {
int exitcode, hulldim;
boolT new_ismalloc;
- static boolT firstcall = True;
coordT *new_points;
- if (firstcall) {
+ if (!qh->qhmem.ferr) {
qh_meminit(qh, errfile);
- firstcall= False;
+ } 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");
qh_exit(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 */
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="errexit">-</a>
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. Exit program\n");
+ 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 */
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="errprint">-</a>
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 */
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="printfacetlist">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhelp_degenerate">-</a>
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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="printhelp_narrowhull">-</a>
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 */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhelp_singular">-</a>
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, -1);
+ 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 */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="user_memsizes">-</a>
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/libqhullr/user_r.h b/src/libqhull_r/user_r.h
similarity index 99%
rename from src/libqhullr/user_r.h
rename to src/libqhull_r/user_r.h
index ce69ee1..0f928ca 100644
--- a/src/libqhullr/user_r.h
+++ b/src/libqhull_r/user_r.h
@@ -1,827 +1,829 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
user.h
user redefinable constants
see qh-user.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 <time.h>
#ifndef qhDEFuser
#define qhDEFuser 1
/*============================================================*/
/*============= qhull library constants ======================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="filenamelen">-</a>
FILENAMElen -- max length for TI and TO filenames
*/
#define qh_FILENAMElen 500
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="msgcode">-</a>
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, 1047, 2059, 3025, 4068, 5003,
- 6243, 7079, 8143, 9410, 10000, 11026]
+ 6260, 7079, 8145, 9410, 10000, 11028]
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 */
#define MSG_FIXUP 11000 /* FIXUP QH11... */
#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="qh_OPTIONline">-</a>
qh_OPTIONline -- max length of an option line 'FO'
*/
#define qh_OPTIONline 80
/*============================================================*/
/*============= data types and configuration macros ==========*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="realT">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="countT">-</a>
countT
The type for counts and identifiers (e.g., the number of points, vertex identifiers)
Typically 'int' or 'long long'.
- May be defined as a unsigned valued (? FIXUP)
+ FIXUP QH11026 countT may be defined as a unsigned value, but several code issues need to be solved first. See countT in Changes.txt
Also defined in qset_r.h
*/
#ifndef DEFcountT
#define DEFcountT 1
typedef int countT;
#endif
#define COUNTmax 0x7fffffff
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="CPUclock">-</a>
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,
<time.h> 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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="RANDOM">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="ORIENTclock">-</a>
qh_ORIENTclock
0 for inward pointing normals by Geomview convention
*/
#define qh_ORIENTclock 0
/*============================================================*/
/*============= joggle constants =============================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEdefault">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEincrease">-</a>
qh_JOGGLEincrease
factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
*/
#define qh_JOGGLEincrease 10.0
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEretry">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEagain">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxincrease">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxretry">-</a>
qh_JOGGLEmaxretry
stop after qh_JOGGLEmaxretry attempts
*/
#define qh_JOGGLEmaxretry 100
/*============================================================*/
/*============= performance related constants ================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="HASHfactor">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="VERIFYdirect">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INITIALsearch">-</a>
qh_INITIALsearch
if qh_INITIALmax, search points up to this dimension
*/
#define qh_INITIALsearch 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INITIALmax">-</a>
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 =============================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMalign">-</a>
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 *))))
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMbufsize">-</a>
qh_MEMbufsize
size of additional memory buffers
notes:
used for qh_meminitbuffers() in global_r.c
*/
#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMinitbuf">-</a>
qh_MEMinitbuf
size of initial memory buffer
notes:
use for qh_meminitbuffers() in global_r.c
*/
#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INFINITE">-</a>
qh_INFINITE
on output, indicates Voronoi center at infinity
*/
#define qh_INFINITE -10.101
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DEFAULTbox">-</a>
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 ======================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="compiler">-</a>
__cplusplus
defined by C++ compilers
__MSC_VER
defined by Microsoft Visual C++
__MWERKS__ && __INTEL__
defined by Metrowerks when compiling for Intel-based Macintosh
__STDC__
defined for strict ANSI C
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="COMPUTEfurthest">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
=0 removes most of statistic gathering and reporting
notes:
if 0, code size is reduced by about 4%.
*/
#define qh_KEEPstatistics 1
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXoutside">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="NOmerge">-</a>
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:
<a href="mem_r.h#NOmem">qh_NOmem</a> in mem_r.c
see user_r.c/user_eg.c for removing io_r.o
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="NOtrace">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="QUICKhelp">-</a>
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.
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DIMmergeVertex">-</a>
qh_DIMmergeVertex
max dimension for vertex merging (it is not effective in high-d)
*/
#define qh_DIMmergeVertex 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DIMreduceBuild">-</a>
qh_DIMreduceBuild
max dimension for vertex reduction during build (slow in high-d)
*/
#define qh_DIMreduceBuild 5
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="BESTcentrum">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="BESTnonconvex">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnewmerges">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnewcentrum">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="COPLANARratio">-</a>
qh_COPLANARratio
for 3-d+ merging, qh.MINvisible is n*premerge_centrum
notes:
for non-merging, it's DISTround
*/
#define qh_COPLANARratio 3
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DISToutside">-</a>
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))
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="RATIOnearinside">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="SEARCHdist">-</a>
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)));
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="USEfindbestnew">-</a>
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)
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WIDEcoplanar">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnarrow">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WARNnarrow">-</a>
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
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="ZEROdelaunay">-</a>
qh_ZEROdelaunay
a zero Delaunay facet occurs for input sites coplanar with their convex hull
the last normal coefficient of a zero Delaunay facet is within
qh_ZEROdelaunay * qh.ANGLEround of 0
notes:
qh_ZEROdelaunay does not allow for joggled input ('QJ').
You can avoid zero Delaunay facets by surrounding the input with a box.
Use option 'PDk:-n' to explicitly define zero Delaunay facets
k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
*/
#define qh_ZEROdelaunay 2
#endif /* qh_DEFuser */
diff --git a/src/libqhullr/usermem_r.c b/src/libqhull_r/usermem_r.c
similarity index 82%
rename from src/libqhullr/usermem_r.c
rename to src/libqhull_r/usermem_r.c
index 83c89b4..3c4a9db 100644
--- a/src/libqhullr/usermem_r.c
+++ b/src/libqhull_r/usermem_r.c
@@ -1,64 +1,65 @@
-/*<html><pre> -<a href="qh-user.htm"
+/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
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 <stdlib.h>
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_exit">-</a>
qh_exit( exitcode )
exit program
notes:
same as exit()
*/
void qh_exit(int exitcode) {
exit(exitcode);
} /* exit */
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_free">-</a>
qh_free(qhT *qh, mem )
free memory
notes:
same as free()
+ No calls to qh_errexit()
*/
void qh_free(void *mem) {
free(mem);
} /* free */
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_malloc">-</a>
qh_malloc( mem )
allocate memory
notes:
same as malloc()
*/
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */
diff --git a/src/libqhullr/userprintf_r.c b/src/libqhull_r/userprintf_r.c
similarity index 83%
rename from src/libqhullr/userprintf_r.c
rename to src/libqhull_r/userprintf_r.c
index 2fbf288..518ee4a 100644
--- a/src/libqhullr/userprintf_r.c
+++ b/src/libqhull_r/userprintf_r.c
@@ -1,64 +1,64 @@
-/*<html><pre> -<a href="qh-user.htm"
+/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_fprintf">-</a>
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)
- fprintf(stderr, "QH6241 qh_fprintf: fp and qh not defined for '%s'", fmt);
- else
- fprintf(qh->qhmem.ferr, "QH6232 qh_fprintf: fp is 0. Was wrong qh_fprintf called for '%s'", fmt);
+ if(!qh){
+ fprintf(stderr, "QH6241 userprintf_r.c: fp and qh not defined for qh_fprintf '%s'", fmt);
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
fprintf(qh->qhmem.ferr, "QH6232 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/libqhullr/userprintf_rbox_r.c b/src/libqhull_r/userprintf_rbox_r.c
similarity index 92%
rename from src/libqhullr/userprintf_rbox_r.c
rename to src/libqhull_r/userprintf_rbox_r.c
index 5af87f6..2aca4d6 100644
--- a/src/libqhullr/userprintf_rbox_r.c
+++ b/src/libqhull_r/userprintf_rbox_r.c
@@ -1,53 +1,53 @@
-/*<html><pre> -<a href="qh-user.htm"
+/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-/*-<a href="qh-user.htm#TOC"
+/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
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) {
fprintf(stderr, "QH6231 Qhull internal error (userprintf_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/libqhullcpp/Coordinates.cpp b/src/libqhullcpp/Coordinates.cpp
index d71e0c9..cb81f70 100644
--- a/src/libqhullcpp/Coordinates.cpp
+++ b/src/libqhullcpp/Coordinates.cpp
@@ -1,184 +1,197 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/Coordinates.cpp#8 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/Coordinates.cpp#10 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
#include "functionObjects.h"
#include "QhullError.h"
#include "Coordinates.h"
#include <iostream>
#include <iterator>
#include <algorithm>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//! Coordinates -- vector of coordT (normally double)
-#//Element access
+#//!\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+=
-#//Read-write
+#//!\name Read-write
+
+void Coordinates::
+append(int pointDimension, coordT *c)
+{
+ if(c){
+ coordT *p= c;
+ for(int i= 0; i<pointDimension; ++i){
+ coordinate_array.push_back(*p++);
+ }
+ }
+}//append dim coordT
coordT Coordinates::
takeAt(countT idx)
{
coordT c= at(idx);
erase(begin()+idx);
return c;
}//takeAt
coordT Coordinates::
takeLast()
{
coordT c= last();
removeLast();
return c;
}//takeLast
void Coordinates::
swap(countT idx, countT other)
{
coordT c= at(idx);
at(idx)= at(other);
at(other)= c;
}//swap
-#//Search
+#//!\name Search
bool Coordinates::
contains(const coordT &t) const
{
CoordinatesIterator i(*this);
return i.findNext(t);
}//contains
countT Coordinates::
count(const coordT &t) const
{
CoordinatesIterator i(*this);
countT result= 0;
while(i.findNext(t)){
++result;
}
return result;
}//count
countT Coordinates::
indexOf(const coordT &t, countT from) const
{
if(from<0){
from += count();
if(from<0){
from= 0;
}
}
if(from<count()){
const_iterator i= begin()+from;
while(i!=constEnd()){
if(*i==t){
return (static_cast<countT>(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<countT>(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/libqhullcpp/Coordinates.h b/src/libqhullcpp/Coordinates.h
index 63af70f..1277105 100644
--- a/src/libqhullcpp/Coordinates.h
+++ b/src/libqhullcpp/Coordinates.h
@@ -1,305 +1,306 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/Coordinates.h#11 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/Coordinates.h#13 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHCOORDINATES_H
#define QHCOORDINATES_H
#include "QhullError.h"
#include "QhullIterator.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <cstddef> // ptrdiff_t, size_t
#include <ostream>
// Requires STL vector class. Can use with another vector class such as QList.
#include <vector>
namespace orgQhull {
#//!\name Defined here
//! An std::vector of point coordinates independent of dimension
- //! Used by PointCoordinates for RboxPoints
+ //! 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<coordT> 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<coordT> &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<coordT> &other) { coordinate_array= other; return *this; }
~Coordinates() {}
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<coordT> toStdVector() const { return coordinate_array; }
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
countT count() const { return static_cast<countT>(size()); }
coordT * data() { return isEmpty() ? 0 : &at(0); }
const coordT * data() const { return const_cast<const pointT*>(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
+ 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
class iterator {
private:
std::vector<coordT>::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<coordT>::iterator &vi) { i= vi; }
iterator & operator=(const iterator &other) { i= other.i; return *this; }
std::vector<coordT>::iterator &base() { return i; }
// No operator-> for base types
coordT & operator*() const { return *i; }
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<other.i; }
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>=other.i; }
// reinterpret_cast to break circular dependency
bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast<const iterator &>(other); }
bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast<const iterator &>(other); }
bool operator<(const Coordinates::const_iterator &other) const { return *this<reinterpret_cast<const iterator &>(other); }
bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast<const iterator &>(other); }
bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast<const iterator &>(other); }
bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast<const iterator &>(other); }
iterator operator++() { return iterator(++i); } //FIXUP QH11012 Should return reference, but get reference to temporary
iterator operator++(int) { return iterator(i++); }
iterator operator--() { return iterator(--i); }
iterator operator--(int) { return iterator(i--); }
iterator operator+=(countT idx) { return iterator(i += idx); }
iterator operator-=(countT idx) { return iterator(i -= idx); }
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<coordT>::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(iterator o) : i(o.i) {}
explicit const_iterator(const std::vector<coordT>::const_iterator &vi) { i= vi; }
const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
// No operator-> for base types
// No reference to a base type for () and []
const coordT & operator*() const { return *i; }
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<other.i; }
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>=other.i; }
const_iterator operator++() { return const_iterator(++i); } //FIXUP QH11014 -- too much copying
const_iterator operator++(int) { return const_iterator(i++); }
const_iterator operator--() { return const_iterator(--i); }
const_iterator operator--(int) { return const_iterator(i--); }
const_iterator operator+=(countT idx) { return const_iterator(i += idx); }
const_iterator operator-=(countT idx) { return const_iterator(i -= idx); }
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/libqhullcpp/PointCoordinates.cpp b/src/libqhullcpp/PointCoordinates.cpp
index c24c92f..c055299 100644
--- a/src/libqhullcpp/PointCoordinates.cpp
+++ b/src/libqhullcpp/PointCoordinates.cpp
@@ -1,342 +1,347 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/PointCoordinates.cpp#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/PointCoordinates.cpp#15 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#include "QhullError.h"
#include "QhullPoint.h"
#include "PointCoordinates.h"
#include <iterator>
#include <iostream>
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
-//! Qhull and QhullQh constructors are the same
PointCoordinates::
-PointCoordinates(const Qhull &q)
-: QhullPoints(q)
+PointCoordinates()
+: QhullPoints()
, point_coordinates()
, describe_points()
{
- makeValid();
}
PointCoordinates::
-PointCoordinates(const Qhull &q, int pointDimension)
-: QhullPoints(q, pointDimension)
+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()
{
- makeValid();
}
PointCoordinates::
PointCoordinates(const Qhull &q, const std::string &aComment)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
- makeValid();
}
PointCoordinates::
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment)
-: QhullPoints(q, pointDimension)
+: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
- makeValid();
+ setDimension(pointDimension);
}
PointCoordinates::
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
-: QhullPoints(q, pointDimension)
+: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
+ setDimension(pointDimension);
append(coordinatesCount, c);
}
PointCoordinates::
-PointCoordinates(QhullQh *qh)
-: QhullPoints(qh)
+PointCoordinates(QhullQh *qqh)
+: QhullPoints(qqh)
, point_coordinates()
, describe_points()
{
- makeValid();
}
PointCoordinates::
-PointCoordinates(QhullQh *qh, int pointDimension)
-: QhullPoints(qh, pointDimension)
-, point_coordinates()
-, describe_points()
-{
- makeValid();
-}
-
-PointCoordinates::
-PointCoordinates(QhullQh *qh, const std::string &aComment)
-: QhullPoints(qh)
+PointCoordinates(QhullQh *qqh, const std::string &aComment)
+: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
- makeValid();
}
PointCoordinates::
-PointCoordinates(QhullQh *qh, int pointDimension, const std::string &aComment)
-: QhullPoints(qh, pointDimension)
+PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment)
+: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
- makeValid();
+ setDimension(pointDimension);
}
PointCoordinates::
-PointCoordinates(QhullQh *qh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
-: QhullPoints(qh, pointDimension)
+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<inDimension){ // Count may precede dimension
std::swap(inCount, inDimension);
}
setDimension(inDimension);
reserveCoordinates(inCount*inDimension);
countT coordinatesCount= 0;
while(!in.eof()){
realT p;
in >> 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
-#//Helpers
+#//!\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<count; i++){
for(int j=0; j<dimension; j++){
os << *c++ << " ";
}
os << endl;
}
return os;
}//operator<<
diff --git a/src/libqhullcpp/PointCoordinates.h b/src/libqhullcpp/PointCoordinates.h
index 88c6c61..b70f6d3 100644
--- a/src/libqhullcpp/PointCoordinates.h
+++ b/src/libqhullcpp/PointCoordinates.h
@@ -1,158 +1,163 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/PointCoordinates.h#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/PointCoordinates.h#14 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHPOINTCOORDINATES_H
#define QHPOINTCOORDINATES_H
#include "QhullPoints.h"
#include "Coordinates.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
#include <string>
#ifndef QHULL_NO_STL
#include <vector>
#endif
namespace orgQhull {
#//!\name Defined here
- //! Zero or more QhullPoints with Coordinates and description
+ //! 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, int pointDimension);
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<coordT>
- explicit PointCoordinates(QhullQh *qh);
- PointCoordinates(QhullQh *qh, int pointDimension);
- PointCoordinates(QhullQh *qh, const std::string &aComment);
- PointCoordinates(QhullQh *qh, int pointDimension, const std::string &aComment);
- PointCoordinates(QhullQh *qh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
+ 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<coordT>
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<coordT> &otherCoordinates) { if(!otherCoordinates.empty()){ append((int)otherCoordinates.size(), &otherCoordinates[0]); } }
std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); }
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
void append(const QList<coordT> &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
QList<coordT> 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); }
- //! defineAs() otherwise disabled
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/libqhullcpp/Qhull.cpp b/src/libqhullcpp/Qhull.cpp
index ab243be..25ecc32 100644
--- a/src/libqhullcpp/Qhull.cpp
+++ b/src/libqhullcpp/Qhull.cpp
@@ -1,313 +1,351 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/Qhull.cpp#16 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/Qhull.cpp#23 $$Change: 1951 $
+** $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
**
****************************************************************************/
#//! Qhull -- invoke qhull from C++
-#//! Compile libqhull and Qhull together due to use of setjmp/longjmp()
+#//! Compile libqhull_r and Qhull together due to use of setjmp/longjmp()
#include "QhullError.h"
#include "RboxPoints.h"
#include "QhullQh.h"
#include "QhullFacet.h"
#include "QhullFacetList.h"
#include "Qhull.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <iostream>
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 {
-#//Global variables
+#//!\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 ";
-#//Constructor, destructor, etc.
+#//!\name Constructor, destructor, etc.
Qhull::
Qhull()
: qh_qh(0)
, origin_point()
, run_called(false)
-, feasiblePoint()
+, feasible_point()
{
allocateQhullQh();
}//Qhull
-//! Invokes Qhull on rboxPoints
+//! 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)
-, feasiblePoint()
+, 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 *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
+Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
: qh_qh(0)
, origin_point()
, run_called(false)
-, feasiblePoint()
+, feasible_point()
{
allocateQhullQh();
- runQhull(inputComment, pointDimension, pointCount, pointCoordinates, qhullCommand2);
+ runQhull(inputComment2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
}//Qhull points
void Qhull::
allocateQhullQh()
{
+ QHULL_LIB_CHECK
+
qh_qh= new QhullQh;
- if(qh_qh!=static_cast<qhT *>(qh_qh)){
- throw QhullError(10074, "Qhull error: QhullQh at a different address than base type QhT (%d bytes). Please report compiler to qhull.org", (int)(static_cast<qhT *>(qh_qh)-qh_qh));
+ void *p= qh_qh;
+ void *p2= static_cast<qhT *>(qh_qh);
+ char *s= static_cast<char *>(p);
+ char *s2= static_cast<char *>(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
-#//GetValue
+//! 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<char*>(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<char *>(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 *qhullCommand2)
+runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
{
if(run_called){
throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed.");
}
run_called= true;
string s("qhull ");
s += qhullCommand2;
char *command= const_cast<char*>(s.c_str());
- /* FIXUP
- 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){
-*/
+ /************* 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<char *>(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);
+ strncat( qh_qh->rbox_command, inputComment2, sizeof(qh_qh->rbox_command)-1);
if(qh_qh->DELAUNAY){
qh_qh->PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput()
}
pointT *newPoints= const_cast<pointT*>(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
-#//Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
+#//!\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(feasiblePoint.isEmpty()){
- qh_fprintf(qh_qh, qh_qh->ferr, 6209, "qhull error: missing feasible point for halfspace intersection. Use option 'Hn,n' or set qh_qh.feasiblePoint\n");
+ 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(feasiblePoint.size()!=(size_t)hulldim){
- qh_fprintf(qh_qh, qh_qh->ferr, 6210, "qhull error: dimension of feasiblePoint should be %d. It is %u", hulldim, feasiblePoint.size());
+ 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=feasiblePoint.begin(); p<feasiblePoint.end(); p++){
+ for(Coordinates::ConstIterator p=feasible_point.begin(); p<feasible_point.end(); p++){
*t++= *p;
}
}
}//initializeFeasiblePoint
}//namespace orgQhull
diff --git a/src/libqhullcpp/Qhull.h b/src/libqhullcpp/Qhull.h
index 93724bc..1d53dc5 100644
--- a/src/libqhullcpp/Qhull.h
+++ b/src/libqhullcpp/Qhull.h
@@ -1,122 +1,133 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/Qhull.h#13 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/Qhull.h#18 $$Change: 1880 $
+** $DateTime: 2015/04/19 21:29:35 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLCPP_H
#define QHULLCPP_H
#include "QhullPoint.h"
#include "QhullVertex.h"
#include "QhullFacet.h"
namespace orgQhull {
/***
Compile qhullcpp and libqhull with the same compiler. setjmp() and longjmp() must be the same.
- #define QHULL_NO_STL
+ #define QHULL_NO_STL
Do not supply conversions to STL
Coordinates.h requires <vector>. 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)
-#//!\name Attribute
public:
- Coordinates feasiblePoint; //! feasible point for half-space intersection
- // FIXUP QH11003 feasiblePoint useOutputStream as field or getter?
-
#//!\name Constructors
- Qhull(); //!< call Qhull::runQhull() next
+ Qhull(); //!< call runQhull() next
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
- Qhull(const char *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, 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.
+private: //! Disable copy constructor and assignment. Qhull owns QhullQh.
Qhull(const Qhull &);
- Qhull &operator=(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; }
- //! non-const due to QhullPoint
+ 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 GetEpsilon
+#//!\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 checkAndFreeQhullMemory() { qh_qh->checkAndFreeQhullMemory(); }
void outputQhull();
void outputQhull(const char * outputflags);
void runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
- void runQhull(const char *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, 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/libqhullcpp/QhullError.h b/src/libqhullcpp/QhullError.h
index 56b6079..d605ded 100644
--- a/src/libqhullcpp/QhullError.h
+++ b/src/libqhullcpp/QhullError.h
@@ -1,62 +1,62 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullError.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullError.h#16 $$Change: 1835 $
+** $DateTime: 2015/02/16 22:32:04 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLERROR_H
#define QHULLERROR_H
#include "RoadError.h"
// No dependencies on libqhull
#ifndef QHULL_ASSERT
#define QHULL_ASSERT assert
#include <assert.h>
#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= 10076,
- NOthrow= 1 //! For flag to UsingLibQhull()
+ 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/libqhullcpp/QhullFacet.cpp b/src/libqhullcpp/QhullFacet.cpp
index bb4bef4..cf86eb9 100644
--- a/src/libqhullcpp/QhullFacet.cpp
+++ b/src/libqhullcpp/QhullFacet.cpp
@@ -1,506 +1,518 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacet.cpp#14 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacet.cpp#16 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
#include "QhullError.h"
#include "Qhull.h"
#include "QhullSet.h"
#include "QhullPoint.h"
#include "QhullPointSet.h"
#include "QhullRidge.h"
#include "QhullFacet.h"
#include "QhullFacetSet.h"
#include "QhullVertex.h"
#include <ostream>
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]
-//! printFormat=qh_PRINTtriangles if return centrum of a Delaunay facet
+//! 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->CENTERtype==qh_ASvoronoi){
+ 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(qh_qh);
+ return QhullPoint();
}//getCenter
//! Return innerplane clearly below the vertices
//! from io_r.c[qh_PRINTinner]
QhullHyperplane QhullFacet::
innerplane() const{
- realT inner;
- // Does not error
- qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), NULL, &inner);
- QhullHyperplane h= hyperplane();
- h.setOffset(h.offset()-inner); //inner is negative
+ QhullHyperplane h;
+ if(qh_qh){
+ realT inner;
+ // Does not error, TRY_QHULL_ not needed
+ qh_outerinner(qh_qh, const_cast<facetT *>(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{
- realT outer;
- // Does not error
- qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), &outer, NULL);
- QhullHyperplane h= hyperplane();
- h.setOffset(h.offset()-outer); //outer is positive
+ QhullHyperplane h;
+ if(qh_qh){
+ realT outer;
+ // Does not error, TRY_QHULL_ not needed
+ qh_outerinner(qh_qh, const_cast<facetT *>(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->CENTERtype!=qh_ASvoronoi){
+ if(qh_qh && qh_qh->CENTERtype!=qh_ASvoronoi){
throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
}
return getCenter();
}//voronoiVertex
-#//Value
+#//!\name Value
//! Disables tricoplanarOwner()
double QhullFacet::
facetArea()
{
- if(!qh_facet->isarea){
+ 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 GetSet<<
+#//!\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; k<numCoords; k++){
os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
}
}else{
for(int k=0; k<numCoords; k++){
os << qh_INFINITE << " "; // FIXUP QH11010 qh_REAL_1
}
}
}else{ // qh CENTERtype==qh_AScentrum
numCoords= pr.facet->qh()->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; k<numCoords; k++){
os << f->center[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 zinc_(Zdistio);
+ // 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();
+ os << f.print("");
return os;
}//<< QhullFacet
diff --git a/src/libqhullcpp/QhullFacet.h b/src/libqhullcpp/QhullFacet.h
index a86fc60..75eb19a 100644
--- a/src/libqhullcpp/QhullFacet.h
+++ b/src/libqhullcpp/QhullFacet.h
@@ -1,151 +1,153 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacet.h#14 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacet.h#19 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACET_H
#define QHULLFACET_H
#include "QhullHyperplane.h"
#include "QhullPoint.h"
#include "QhullSet.h"
#include "QhullPointSet.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Coordinates;
class Qhull;
class QhullFacetSet;
class QhullRidge;
class QhullVertex;
class QhullVertexSet;
#//!\name Defined here
class QhullFacet;
typedef QhullSet<QhullRidge> 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; //! May be 0 (!isDefined) for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
- QhullQh * qh_qh; //! qhT
+ 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 *qh) : qh_facet(&s_empty_facet), qh_qh(qh) {}
- QhullFacet(QhullQh *qh, facetT *f) : qh_facet(f ? f : &s_empty_facet), qh_qh(qh) {}
+ 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>
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->hull_dim; }
+ 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<QhullFacet>
// 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 : -1); }
+ countT id() const { return (qh_facet ? qh_facet->id : (int)qh_IDunknown); }
QhullHyperplane innerplane() const;
- bool isDefined() const { return qh_facet && qh_facet != &s_empty_facet; }
+ 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<coordT *>(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()
- explicit PrintFacet(QhullFacet &f) : facet(&f) {}
+ const char * message;
+ explicit PrintFacet(QhullFacet &f, const char * s) : facet(&f), message(s) {}
};//PrintFacet
- PrintFacet print() { return PrintFacet(*this); }
+ 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, const orgQhull::QhullFacet::PrintFacet &pr);
std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
#endif // QHULLFACET_H
diff --git a/src/libqhullcpp/QhullFacetList.cpp b/src/libqhullcpp/QhullFacetList.cpp
index 1a042c5..4005924 100644
--- a/src/libqhullcpp/QhullFacetList.cpp
+++ b/src/libqhullcpp/QhullFacetList.cpp
@@ -1,172 +1,173 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacetList.cpp#8 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacetList.cpp#9 $$Change: 1816 $
+** $DateTime: 2015/01/21 22:51:49 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacetList -- Qhull's linked facets, as a C++ class
#include "QhullFacet.h"
#include "QhullFacetList.h"
#include "QhullPoint.h"
#include "QhullRidge.h"
#include "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>(QhullFacet(q, b), QhullFacet(q, e))
, select_all(false)
{
}
#//!\name Conversions
// See qt_qhull.cpp for QList conversions
#ifndef QHULL_NO_STL
std::vector<QhullFacet> QhullFacetList::
toStdVector() const
{
QhullLinkedListIterator<QhullFacet> i(*this);
std::vector<QhullFacet> 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<QhullVertex> QhullFacetList::
vertices_toStdVector() const
{
std::vector<QhullVertex> 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<QhullFacet>::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<QhullFacet>::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<QhullFacet>::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();
+ 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/libqhullcpp/QhullFacetList.h b/src/libqhullcpp/QhullFacetList.h
index 20348f5..917f6b8 100644
--- a/src/libqhullcpp/QhullFacetList.h
+++ b/src/libqhullcpp/QhullFacetList.h
@@ -1,104 +1,106 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacetList.h#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacetList.h#12 $$Change: 1835 $
+** $DateTime: 2015/02/16 22:32:04 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACETLIST_H
#define QHULLFACETLIST_H
#include "QhullLinkedList.h"
#include "QhullFacet.h"
#include <ostream>
#ifndef QHULL_NO_STL
#include <vector>
#endif
namespace orgQhull {
#//!\name Used here
class Qhull;
class QhullFacet;
class QhullQh;
#//!\name Defined here
- //! QhullFacetList -- List of Qhull facets, as a C++ class. See QhullFacetSet.h
+ //! QhullFacetList -- List of QhullFacet/facetT, as a C++ class.
+ //!\see QhullFacetSet.h
class QhullFacetList;
//! QhullFacetListIterator -- if(f.isGood()){ ... }
typedef QhullLinkedListIterator<QhullFacet> QhullFacetListIterator;
class QhullFacetList : public QhullLinkedList<QhullFacet> {
#//!\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 *qh, facetT *b, facetT *e);
+ QhullFacetList(QhullQh *qqh, facetT *b, facetT *e);
QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList<QhullFacet>(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<QhullFacet>(*other.begin(), *other.end()), select_all(other.select_all) {}
- QhullFacetList & operator=(const QhullFacetList &other) { QhullLinkedList<QhullFacet>::operator =(other); select_all= other.select_all; }
+ QhullFacetList & operator=(const QhullFacetList &other) { QhullLinkedList<QhullFacet>::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<QhullFacet> toStdVector() const;
std::vector<QhullVertex> vertices_toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullFacet> toQList() const;
QList<QhullVertex> 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;
- PrintFacetList(const QhullFacetList &fl) : facet_list(&fl) {}
+ const char * print_message; //!< non-null message
+ PrintFacetList(const QhullFacetList &fl, const char *message) : facet_list(&fl), print_message(message) {}
};//PrintFacetList
- PrintFacetList print() const { return PrintFacetList(*this); }
+ 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/libqhullcpp/QhullFacetSet.h b/src/libqhullcpp/QhullFacetSet.h
index f0f371f..eb40920 100644
--- a/src/libqhullcpp/QhullFacetSet.h
+++ b/src/libqhullcpp/QhullFacetSet.h
@@ -1,96 +1,97 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacetSet.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacetSet.h#14 $$Change: 1835 $
+** $DateTime: 2015/02/16 22:32:04 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACETSET_H
#define QHULLFACETSET_H
#include "QhullSet.h"
-#include "QhullFacet.h"
+#include "QhullFacet.h"
#include <ostream>
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<QhullFacet> QhullFacetSetIterator;
class QhullFacetSet : public QhullSet<QhullFacet> {
#//!\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<QhullFacet>(q, s), select_all(false) {}
- QhullFacetSet(QhullQh *qh, setT *s) : QhullSet<QhullFacet>(qh, s), select_all(false) {}
- //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
+ QhullFacetSet(QhullQh *qqh, setT *s) : QhullSet<QhullFacet>(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<QhullFacet>(other), select_all(other.select_all) {}
- QhullFacetSet & operator=(const QhullFacetSet &other) { QhullSet<QhullFacet>::operator=(other); select_all= other.select_all; }
+ //!Assignment copies pointers but not contents.
+ QhullFacetSet & operator=(const QhullFacetSet &other) { QhullSet<QhullFacet>::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<QhullFacet> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullFacet> 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;
+ 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;
+ 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/libqhullcpp/QhullHyperplane.cpp b/src/libqhullcpp/QhullHyperplane.cpp
index 480a757..4500640 100644
--- a/src/libqhullcpp/QhullHyperplane.cpp
+++ b/src/libqhullcpp/QhullHyperplane.cpp
@@ -1,185 +1,187 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullHyperplane.cpp#11 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullHyperplane.cpp#17 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#include "QhullHyperplane.h"
#include "Qhull.h"
#include "QhullPoint.h"
#include <iostream>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Constructors
QhullHyperplane::
QhullHyperplane(const Qhull &q)
: hyperplane_coordinates(0)
-, hyperplane_dimension(0)
-, hyperplane_offset(0.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)
-, hyperplane_dimension(hyperplaneDimension)
-, hyperplane_offset(hyperplaneOffset)
, 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<coordT> QhullHyperplane::
toStdVector() const
{
QhullHyperplaneIterator i(*this);
std::vector<coordT> 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){
+ 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->distanceEpsilon()){
+ if(d > (qh_qh ? qh_qh->distanceEpsilon() : 0.0)){
return false;
}
- const coordT *c= hyperplane_coordinates;
- const coordT *c2= other.hyperplane_coordinates;
- if(c==c2){
- return true;
- }
- double dist2= 0.0;
- for(int k= hyperplane_dimension; k--; ){
- double diff= *c++ - *c2++;
- dist2 += diff*diff;
- }
- if(dist2 > qh_qh->angleEpsilon()){
+ 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
+{
+ 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();
+ os << p.print("");
return os;
}
ostream &
operator<<(ostream &os, const QhullHyperplane::PrintHyperplane &pr)
{
- if(pr.print_message){
- os << pr.print_message;
- }
+ 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
}
}
- if(pr.hyperplane_offset_message){
- os << pr.hyperplane_offset_message << " " << p.offset();
- }else{
- os << " " << p.offset();
- }
+ os << pr.hyperplane_offset_message << " " << p.offset();
os << std::endl;
return os;
}//PrintHyperplane
diff --git a/src/libqhullcpp/QhullHyperplane.h b/src/libqhullcpp/QhullHyperplane.h
index 93abf3c..e711cbe 100644
--- a/src/libqhullcpp/QhullHyperplane.h
+++ b/src/libqhullcpp/QhullHyperplane.h
@@ -1,123 +1,125 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullHyperplane.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullHyperplane.h#18 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHHYPERPLANE_H
#define QHHYPERPLANE_H
#include "QhullError.h"
#include "QhullIterator.h"
#include "QhullQh.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
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; // Keep pointers aligned
- int hyperplane_dimension;
- coordT hyperplane_offset;
- QhullQh * qh_qh;
+ 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(const Qhull &q);
+ 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);
- QhullHyperplane(QhullQh *qh) : hyperplane_coordinates(0), hyperplane_dimension(0), hyperplane_offset(0.0), qh_qh(qh) {}
- QhullHyperplane(QhullQh *qh, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) : hyperplane_coordinates(c), hyperplane_dimension(hyperplaneDimension), hyperplane_offset(hyperplaneOffset), qh_qh(qh) {}
+ 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), hyperplane_dimension(other.hyperplane_dimension), hyperplane_offset(other.hyperplane_offset), qh_qh(other.qh_qh) {}
+ 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>
- QhullHyperplane & operator=(const QhullHyperplane &other) { hyperplane_coordinates= other.hyperplane_coordinates; hyperplane_dimension= other.hyperplane_dimension; hyperplane_offset= other.hyperplane_offset; qh_qh= other.qh_qh; return *this; }
+ 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<coordT> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> 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 isDefined() const { return hyperplane_coordinates!=0 && hyperplane_dimension>0; }
+ 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<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
coordT & operator[](int idx) { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
void setCoordinates(coordT *c) { hyperplane_coordinates= c; }
void setDimension(int hyperplaneDimension) { hyperplane_dimension= hyperplaneDimension; }
void setOffset(coordT hyperplaneOffset) { hyperplane_offset= hyperplaneOffset; }
#//!\name iterator
iterator begin() { return hyperplane_coordinates; }
const_iterator begin() const { return hyperplane_coordinates; }
const_iterator constBegin() const { return hyperplane_coordinates; }
const_iterator constEnd() const { return hyperplane_coordinates+hyperplane_dimension; }
int count() { return hyperplane_dimension; }
iterator end() { return hyperplane_coordinates+hyperplane_dimension; }
const_iterator end() const { return hyperplane_coordinates+hyperplane_dimension; }
size_t size() { return (size_t)hyperplane_dimension; }
#//!\name Methods
double distance(const QhullPoint &p) const;
+ double hyperplaneAngle(const QhullHyperplane &other) const;
double norm() const;
#//!\name IO
struct PrintHyperplane{
- const QhullHyperplane *hyperplane;
- const char * print_message; //!< Different output if 0
- const char * hyperplane_offset_message; //!< Different output if 0
+ const QhullHyperplane *hyperplane;
+ const char * print_message; //!< non-null message
+ const char * hyperplane_offset_message; //!< non-null message
PrintHyperplane(const char *message, const char *offsetMessage, const QhullHyperplane &p) : hyperplane(&p), print_message(message), hyperplane_offset_message(offsetMessage) {}
};//PrintHyperplane
- PrintHyperplane print() const { return PrintHyperplane(0, 0, *this); }
+ PrintHyperplane print(const char *message) const { return PrintHyperplane(message, "", *this); }
PrintHyperplane print(const char *message, const char *offsetMessage) const { return PrintHyperplane(message, offsetMessage, *this); }
};//QhullHyperplane
QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullHyperplane, coordT)
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane::PrintHyperplane &pr);
-std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p); //FIXUP QH11015 -- multiple instances if define here
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p);
#endif // QHHYPERPLANE_H
diff --git a/src/libqhullcpp/QhullIterator.h b/src/libqhullcpp/QhullIterator.h
index 3d0becf..260e92f 100644
--- a/src/libqhullcpp/QhullIterator.h
+++ b/src/libqhullcpp/QhullIterator.h
@@ -1,171 +1,174 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullIterator.h#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullIterator.h#12 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLITERATOR_H
#define QHULLITERATOR_H
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <assert.h>
#include <string>
#include <vector>
//! Avoid dependence on <iterator>
namespace std { struct bidirectional_iterator_tag; struct random_access_iterator_tag; }
namespace orgQhull {
#//!\name Defined here
//! 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_()
// Changed c to C* as in Mutable... Assumes c does not go away.
#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 T> \
class Qhull##C##Iterator \
{ \
typedef typename Qhull##C<T>::const_iterator const_iterator; \
Qhull##C<T> c; \
const_iterator i; \
public: \
inline Qhull##C##Iterator(const Qhull##C<T> &container) \
: c(container), i(c.constBegin()) {} \
inline Qhull##C##Iterator &operator=(const Qhull##C<T> &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 T> \
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/libqhullcpp/QhullLinkedList.h b/src/libqhullcpp/QhullLinkedList.h
index 90877d5..ced2a04 100644
--- a/src/libqhullcpp/QhullLinkedList.h
+++ b/src/libqhullcpp/QhullLinkedList.h
@@ -1,380 +1,385 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullLinkedList.h#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullLinkedList.h#14 $$Change: 1931 $
+** $DateTime: 2015/07/12 21:29:14 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLLINKEDLIST_H
#define QHULLLINKEDLIST_H
-namespace std { struct bidirectional_iterator_tag; struct random_access_iterator_tag; }
+namespace std {
+ struct bidirectional_iterator_tag;
+ struct random_access_iterator_tag;
+}//std
#include "QhullError.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
+#include <cstddef> // ptrdiff_t, size_t
+
#ifdef QHULL_USES_QT
#include <QtCore/QList>
#endif
#ifndef QHULL_NO_STL
#include <algorithm>
#endif
namespace orgQhull {
#//!\name Defined here
//! QhullLinkedList<T> -- 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.
- //! libqhull owns the contents.
+ //! 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<T>::const_iterator -- STL-style iterator
//! QhullLinkedList<T>::iterator -- STL-style iterator
//! QhullLinkedListIterator<T> -- Java-style iterator
//! Derived from Qt/core/tools/qiterator.h
//! Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h]
template <typename T>
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>(T b, T e) : begin_node(b), end_node(e) {}
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
QhullLinkedList<T>(const QhullLinkedList<T> &other) : begin_node(other.begin_node), end_node(other.end_node) {}
- QhullLinkedList<T> & operator=(const QhullLinkedList<T> &other) { begin_node= other.begin_node; end_node= other.end_node; }
+ QhullLinkedList<T> & operator=(const QhullLinkedList<T> &other) { begin_node= other.begin_node; end_node= other.end_node; return *this; }
~QhullLinkedList<T>() {}
private:
//!disabled since a sentinel must be allocated as the private type
QhullLinkedList<T>() {}
//!disabled since qs= qs2 is ambiguous (pointer vs. contents)
public:
#//!\name Conversions
#ifndef QHULL_NO_STL
std::vector<T> toStdVector() const;
#endif
#ifdef QHULL_USES_QT
QList<T> 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<T> &o) const;
bool operator!=(const QhullLinkedList<T> &o) const { return !operator==(o); }
size_t size() const { return count(); }
#//!\name Element access
//! Return by value which contains a pointer (e.g., typedef vertexT * QhullVertex). A reference does not make sense.
T back() const { return last(); }
T first() const { QHULL_ASSERT(!isEmpty()); return *begin(); }
T front() const { return first(); }
T last() const { 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(T t) : i(t) {}
+ 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; }
T operator*() const { return i; }
T operator->() const { 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<const iterator &>(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(T t) : i(t) {}
+ 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(iterator o) : i(o.i) {}
const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; }
T operator*() const { return i; }
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 <typename T>
class QhullLinkedListIterator // FIXUP QH11016 define QhullMutableLinkedListIterator
{
typedef typename QhullLinkedList<T>::const_iterator const_iterator;
const QhullLinkedList<T> *c;
const_iterator i;
public:
QhullLinkedListIterator(const QhullLinkedList<T> &container) : c(&container), i(c->constBegin()) {}
- QhullLinkedListIterator &operator=(const QhullLinkedList<T> &container) { c= &container; i= c->constBegin(); return *this; }
+ QhullLinkedListIterator & operator=(const QhullLinkedList<T> &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 <typename T>
std::vector<T> QhullLinkedList<T>::
toStdVector() const
{
std::vector<T> tmp;
std::copy(constBegin(), constEnd(), std::back_inserter(tmp));
return tmp;
}//toStdVector
#endif
#ifdef QHULL_USES_QT
template <typename T>
QList<T> QhullLinkedList<T>::
toQList() const
{
QhullLinkedListIterator<T> i(*this);
QList<T> ls;
while(i.hasNext()){
ls.append(i.next());
}
return ls;
}//toQList
#endif
#//!\name GetSet
template <typename T>
countT QhullLinkedList<T>::
count() const
{
const_iterator i= begin_node;
countT c= 0;
while(i != end_node){
c++;
i++;
}
return c;
}//count
#//!\name Search
template <typename T>
bool QhullLinkedList<T>::
contains(const T &t) const
{
const_iterator i= begin_node;
while(i != end_node){
if(i==t){
return true;
}
i++;
}
return false;
}//contains
template <typename T>
countT QhullLinkedList<T>::
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 <typename T>
bool QhullLinkedList<T>::
operator==(const QhullLinkedList<T> &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<T>(i.next());
il= static_cast<T>(il.next());
}
if(il != l.end_node){
return false;
}
return true;
}//operator==
#//!\name Iterator
template <typename T>
typename QhullLinkedList<T>::iterator QhullLinkedList<T>::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 T>
typename QhullLinkedList<T>::const_iterator QhullLinkedList<T>::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 <typename T>
bool QhullLinkedListIterator<T>::
findNext(const T &t)
{
while(i != c->constEnd()){
if (*i++ == t){
return true;
}
}
return false;
}//findNext
template <typename T>
bool QhullLinkedListIterator<T>::
findPrevious(const T &t)
{
while(i!=c->constBegin()){
if(*(--i)==t){
return true;
}
}
return false;
}//findNext
}//namespace orgQhull
#//!\name Global
template <typename T>
std::ostream &
operator<<(std::ostream &os, const orgQhull::QhullLinkedList<T> &qs)
{
typename orgQhull::QhullLinkedList<T>::const_iterator i;
for(i= qs.begin(); i != qs.end(); ++i){
os << *i;
}
return os;
}//operator<<
#endif // QHULLLINKEDLIST_H
diff --git a/src/libqhullcpp/QhullPoint.cpp b/src/libqhullcpp/QhullPoint.cpp
index 1cc0a63..01f3809 100644
--- a/src/libqhullcpp/QhullPoint.cpp
+++ b/src/libqhullcpp/QhullPoint.cpp
@@ -1,189 +1,202 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoint.cpp#13 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoint.cpp#15 $$Change: 1814 $
+** $DateTime: 2015/01/20 21:27:58 $$Author: bbarber $
**
****************************************************************************/
#include "QhullPoint.h"
#include "QhullError.h"
#include "Qhull.h"
#include <iostream>
#include <algorithm>
#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<coordT> QhullPoint::
toStdVector() const
{
QhullPointIterator i(*this);
std::vector<coordT> 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, or if the distance between the points is less than sqrt(qh_qh->distanceEpsilon())
-//! Uses sqrt() since distanceEpsilon is the roundoff for distance to hyperplane, i.e., the inner product
+//! 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 || !qh_qh){
+ 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;
}
- return (dist2 < qh_qh->distanceEpsilon()); // dist2 is distance()^2
+ 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!=-1)){
+ 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/libqhullcpp/QhullPoint.h b/src/libqhullcpp/QhullPoint.h
index 284dcf9..3a08c1c 100644
--- a/src/libqhullcpp/QhullPoint.h
+++ b/src/libqhullcpp/QhullPoint.h
@@ -1,131 +1,138 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoint.h#16 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoint.h#21 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHPOINT_H
#define QHPOINT_H
#include "QhullError.h"
#include "QhullIterator.h"
#include "QhullQh.h"
#include "Coordinates.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
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 point in Qhull is an array of coordinates.
+//! 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. Used by id() and operator=()
+ 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, int pointDimension, coordT *c);
QhullPoint(const Qhull &q, coordT *c);
QhullPoint(const Qhull &q, Coordinates &c);
- explicit QhullPoint(QhullQh *qh) : point_coordinates(0), qh_qh(qh), point_dimension(qh->hull_dim) {}
- QhullPoint(QhullQh *qh, int pointDimension, coordT *c) : point_coordinates(c), qh_qh(qh), point_dimension(pointDimension) {}
- QhullPoint(QhullQh *qh, coordT *c) : point_coordinates(c), qh_qh(qh), point_dimension(qh->hull_dim) {}
- QhullPoint(QhullQh *qh, Coordinates &c) : point_coordinates(c.data()), qh_qh(qh), point_dimension(c.count()) {}
- // Creates an alias. Does not copy the point. Needed for return by value and parameter passing.
- QhullPoint(const QhullPoint &other) : point_coordinates(other.point_coordinates), point_dimension(other.point_dimension), qh_qh(other.qh_qh) {}
- // Creates an alias. Does not copy the point. Needed for vector<QhullPoint>
- QhullPoint & operator=(const QhullPoint &other) { point_coordinates= other.point_coordinates; point_dimension= other.point_dimension; qh_qh= other.qh_qh; return *this; }
+ 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>
+ 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<coordT> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> 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; }
- //! Creates an alias, but does not change qh()
- void defineAs(QhullPoint &other) { point_coordinates= other.point_coordinates; point_dimension= other.point_dimension; }
+ 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 QhullSet<QhullPoint>
+ coordT * getBaseT() const { return point_coordinates; } // for QhullPointSet
countT id() const { return qh_pointid(qh_qh, point_coordinates); } // NOerrors
- bool isDefined() const { return (point_coordinates!=0 && point_dimension>0); };
+ 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); }
+ bool operator!=(const QhullPoint &other) const { return ! operator==(other); }
const coordT & operator[](int idx) const { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
coordT & operator[](int idx) { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
QhullQh * qh() { return qh_qh; }
void setCoordinates(coordT *c) { point_coordinates= c; }
void setDimension(int pointDimension) { point_dimension= pointDimension; }
#//!\name foreach
iterator begin() { return point_coordinates; }
const_iterator begin() const { return point_coordinates; }
const_iterator constBegin() const { return point_coordinates; }
const_iterator constEnd() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
int count() { return (point_coordinates ? point_dimension : 0); }
iterator end() { return (point_coordinates ? point_coordinates+point_dimension : 0); }
const_iterator end() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
size_t size() { return (size_t)(point_coordinates ? point_dimension : 0); }
#//!\name Methods
void advancePoint(countT idx) { if(point_coordinates) { point_coordinates += idx*point_dimension; } }
double distance(const QhullPoint &p) const;
#//!\name IO
struct PrintPoint{
const QhullPoint *point;
const char * point_message;
bool with_identifier;
PrintPoint(const char *message, bool withIdentifier, const QhullPoint &p) : point(&p), point_message(message), with_identifier(withIdentifier) {}
};//PrintPoint
PrintPoint print(const char *message) const { return PrintPoint(message, false, *this); }
PrintPoint printWithIdentifier(const char *message) const { return PrintPoint(message, true, *this); }
};//QhullPoint
QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullPoint, coordT)
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint::PrintPoint &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint &p);
#endif // QHPOINT_H
diff --git a/src/libqhullcpp/QhullPointSet.cpp b/src/libqhullcpp/QhullPointSet.cpp
index aed8159..af45677 100644
--- a/src/libqhullcpp/QhullPointSet.cpp
+++ b/src/libqhullcpp/QhullPointSet.cpp
@@ -1,209 +1,62 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullPointSet.cpp#14 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullPointSet.cpp#15 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#include "QhullPointSet.h"
#include <iostream>
#include <algorithm>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
-#//!\name Conversions
-
-/************** FIXUP
-// See qt-qhull.cpp for QList conversion
-
-#ifndef QHULL_NO_STL
-std::vector<QhullPoint> QhullPointSet::
-toStdVector() const
-{
- QhullPointSetIterator i(*this);
- std::vector<QhullPoint> vs;
- while(i.hasNext()){
- vs.push_back(i.next());
- }
- return vs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#//!\name GetSet
-
-bool QhullPointSet::
-operator==(const QhullPointSet &o) const
-{
- if(dimension()!=o.dimension() || count()!=o.count()){
- return false;
- }
- QhullPointSetIterator i(*this);
- QhullPointSetIterator j(o);
- while(i.hasNext()){
- if(i.next()!=j.next()){
- return false;
- }
- }
- return true;
-}//operator==
-
-//! Derived from QhullSet::value
-//! Returns QhullPoint() on error
-QhullPoint QhullPointSet::
-value(countT idx) const
-{
- // Avoid error in qh_setsize() and assert in elementPointer()
- //const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
- void **n= reinterpret_cast<void **>(&SETelem_(getSetT(), idx));
- coordT **n2= reinterpret_cast<coordT **>(n);
- if(idx>=0 && n<endPointer()){
- return QhullPoint(qh(), *n2);
- }else{
- return QhullPoint(qh());
- }
-}//value
-
-//! Non-const since copy is an alias
-//! Derived from QhullSet::value
-QhullPoint QhullPointSet::
-value(countT idx, QhullPoint &defaultValue) const
-{
- // Avoid call to qh_setsize() and assert in elementPointer()
- void **n= reinterpret_cast<void **>(&SETelem_(getSetT(), idx));
- coordT **n2= reinterpret_cast<coordT **>(n);
- if(idx>=0 && n<endPointer()){
- return QhullPoint(qh(), dimension(), *n2);
- }else{
- return defaultValue;
- }
-}//value
-
-#//!\name Methods
-
-bool QhullPointSet::
-contains(const QhullPoint &t) const
-{
- QhullPointSetIterator i(*this);
- while(i.hasNext()){
- if(i.next()==t){
- return true;
- }
- }
- return false;
-}//contains
-
-countT QhullPointSet::
-count(const QhullPoint &t) const
-{
- countT n= 0;
- QhullPointSetIterator i(*this);
- while(i.hasNext()){
- if(i.next()==t){
- ++n;
- }
- }
- return n;
-}//count
-
-countT QhullPointSet::
-indexOf(const QhullPoint &t) const
-{
- countT idx= 0;
- QhullPointSetIterator i(*this);
- while(i.hasNext()){
- if(i.next()==t){
- return idx;
- }
- ++idx;
- }
- return -1;
-}//indexOf
-
-countT QhullPointSet::
-lastIndexOf(const QhullPoint &t) const
-{
- countT idx= count()-1;
- QhullPointSetIterator i(*this);
- i.toBack();
- while(i.hasPrevious()){
- if(i.previous()==t){
- break;
- }
- --idx;
- }
- return idx;
-}//lastIndexOf
-*/
-/**************** FIXUP
-#//QhullPointSetIterator
-
-bool QhullPointSetIterator::
-findNext(const QhullPoint &p)
-{
- while(i!=c->constEnd()){
- if(*i++ == p){
- return true;
- }
- }
- return false;
-}//findNext
-
-bool QhullPointSetIterator::
-findPrevious(const QhullPoint &p)
-{
- while(i!=c->constBegin()){
- if(*(--i) == p){
- return true;
- }
- }
- return false;
-}//findPrevious
-*/
+// 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/libqhullcpp/QhullPointSet.h b/src/libqhullcpp/QhullPointSet.h
index a04d8c0..3c2af4a 100644
--- a/src/libqhullcpp/QhullPointSet.h
+++ b/src/libqhullcpp/QhullPointSet.h
@@ -1,78 +1,79 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullPointSet.h#15 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullPointSet.h#18 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLPOINTSET_H
#define QHULLPOINTSET_H
#include "QhullSet.h"
#include "QhullPoint.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
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<QhullPoint> {
private:
#//!\name Fields
// no fields
public:
#//!\name Construct
QhullPointSet(const Qhull &q, setT *s) : QhullSet<QhullPoint>(q, s) {}
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
- QhullPointSet(QhullQh *qh, setT *s) : QhullSet<QhullPoint>(qh, s) {}
+ QhullPointSet(QhullQh *qqh, setT *s) : QhullSet<QhullPoint>(qqh, s) {}
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
QhullPointSet(const QhullPointSet &other) : QhullSet<QhullPoint>(other) {}
- QhullPointSet & operator=(const QhullPointSet &other) { QhullSet<QhullPoint>::operator=(other); }
+ //!Assignment copies pointers but not contents.
+ QhullPointSet & operator=(const QhullPointSet &other) { QhullSet<QhullPoint>::operator=(other); return *this; }
~QhullPointSet() {}
//!Default constructor disabled.
private:
QhullPointSet();
public:
#//!\name IO
struct PrintIdentifiers{
const QhullPointSet *point_set;
- const char * print_message;
+ 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;
+ 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<QhullPoint> 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/libqhullcpp/QhullPoints.cpp b/src/libqhullcpp/QhullPoints.cpp
index f49e9ab..c2a5cd6 100644
--- a/src/libqhullcpp/QhullPoints.cpp
+++ b/src/libqhullcpp/QhullPoints.cpp
@@ -1,303 +1,319 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoints.cpp#11 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoints.cpp#14 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#include "QhullPoints.h"
#include "Qhull.h"
#include <iostream>
#ifndef QHULL_NO_STL
#include <vector>
#endif
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Constructors
QhullPoints::
-QhullPoints(const Qhull &q)
+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, int pointDimension)
-: point_first(0)
-, point_end(0)
+QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c)
+: point_first(c)
+, point_end(c+coordinateCount2)
, qh_qh(q.qh())
-, point_dimension(pointDimension)
+, point_dimension(q.hullDimension())
{
- QHULL_ASSERT(pointDimension>=0);
+ QHULL_ASSERT(q.hullDimension());
+ QHULL_ASSERT(coordinateCount2>=0);
}//QhullPoints Qhull dim
QhullPoints::
-QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c)
+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 *qh, int pointDimension, countT coordinateCount2, coordT *c)
+QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c)
: point_first(c)
, point_end(c+coordinateCount2)
-, qh_qh(qh)
+, 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<QhullPoint> QhullPoints::
toStdVector() const
{
QhullPointsIterator i(*this);
std::vector<QhullPoint> 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;
}
- const coordT *c= point_first;
- const coordT *c2= other.point_first;
- while(c<point_end){
- if(*c++!=*c2++){
- return false;
+ if(!qh_qh || qh_qh->hull_dim==0){
+ const coordT *c= point_first;
+ const coordT *c2= other.point_first;
+ while(c<point_end){
+ if(*c++!=*c2++){
+ return false;
+ }
+ }
+ }else{
+ const_iterator i= begin();
+ const_iterator i2= other.begin();
+ while(i<end()){
+ if(*i++!=*i2++){
+ return false;
+ }
}
}
return true;
}//operator==
+//! Reset QhullPoints to QhullQh and its hullDimension()
+//! Does not free up old qh_qh
void QhullPoints::
-setQhullQh(QhullQh *qh)
+resetQhullQh(QhullQh *qqh)
{
- if(qh && qh_qh){
- throw QhullError(10073, "Qhull error: QhullQh already set for QhullPoints");
- }
- qh_qh= qh;
-}//setQhullQh
+ qh_qh= qqh;
+ point_dimension= (qqh ? qqh->hull_dim : 0);
+ point_first= 0;
+ point_end= 0;
+}//resetQhullQh
QhullPoint QhullPoints::
value(countT idx) const
{
QhullPoint p(qh_qh);
if(idx>=0 && idx<count()){
- p.defineAs(qh_qh->hull_dim, point_first+idx*qh_qh->hull_dim);
+ p.defineAs(point_dimension, point_first+idx*point_dimension);
}
return p;
}//value
QhullPoint QhullPoints::
value(countT idx, QhullPoint &defaultValue) const
{
QhullPoint p(qh_qh);
if(idx>=0 && idx<count()){
- p.defineAs(qh_qh->hull_dim, point_first+idx*qh_qh->hull_dim);
+ p.defineAs(point_dimension, point_first+idx*point_dimension);
}else{
p.defineAs(defaultValue);
}
return p;
}//value
-#//! Methods
+#//!\name Methods
bool QhullPoints::
contains(const QhullPoint &t) const
{
const_iterator i= begin();
while(i != end()){
if(*i==t){
return true;
}
i++;
}
return false;
}//contains
countT QhullPoints::
count(const QhullPoint &t) const
{
countT n= 0;
const_iterator i= begin();
while(i != end()){
if(*i==t){
++n;
}
i++;
}
return n;
}//count
countT QhullPoints::
indexOf(const coordT *pointCoordinates) const
{
if(!includesCoordinates(pointCoordinates) || point_dimension==0){
return -1;
}
size_t offset= pointCoordinates-point_first;
countT idx= (countT)(offset/(size_t)point_dimension);
countT extra= (countT)(offset%(size_t)point_dimension);
if(extra!=0){
throw QhullError(10066, "Qhull error: coordinates %x are not at point boundary (extra %d at index %d)", extra, idx, 0.0, pointCoordinates);
}
return idx;
}//indexOf coordT
countT QhullPoints::
indexOf(const coordT *pointCoordinates, int noThrow) const
{
size_t extra= 0;
if(noThrow){
if(!includesCoordinates(pointCoordinates) || point_dimension==0){
return -1;
}
extra= (pointCoordinates-point_first)%(size_t)point_dimension;
}
return indexOf(pointCoordinates-extra);
}//indexOf coordT noThrow
countT QhullPoints::
indexOf(const QhullPoint &t) const
{
countT j=0;
const_iterator i= begin();
while(i!=end()){
if(*i==t){
return j;
}
++i;
++j;
}
return -1;
}//indexOf
countT QhullPoints::
lastIndexOf(const QhullPoint &t) const
{
countT j= count();
const_iterator i= end();
while(i != begin()){
--i;
--j;
if(*i==t){
return j;
}
}
return -1;
}//lastIndexOf
QhullPoints QhullPoints::
mid(countT idx, countT length) const
{
countT n= count();
if(idx<0 || idx>=n){
n= 0;
}else if(length<0 || idx+length>=n){
n -= idx;
}else{
n -= idx+length;
}
- return QhullPoints(qh_qh, qh_qh->hull_dim, n*qh_qh->hull_dim, point_first+idx*qh_qh->hull_dim);
+ 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<<QhullPoints
ostream &
operator<<(ostream &os, const QhullPoints::PrintPoints &pr)
{
os << pr.point_message;
QhullPoints ps= *pr.points;
for(QhullPoints::iterator i=ps.begin(); i!=ps.end(); ++i){
QhullPoint p= *i;
if(pr.with_identifier){
os << p.printWithIdentifier("");
}else{
os << p.print("");
}
}
return os;
}//<<PrintPoints
diff --git a/src/libqhullcpp/QhullPoints.h b/src/libqhullcpp/QhullPoints.h
index ea35337..2316bac 100644
--- a/src/libqhullcpp/QhullPoints.h
+++ b/src/libqhullcpp/QhullPoints.h
@@ -1,246 +1,256 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoints.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullPoints.h#17 $$Change: 1931 $
+** $DateTime: 2015/07/12 21:29:14 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLPOINTS_H
#define QHULLPOINTS_H
#include "QhullPoint.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
+#include <cstddef> // ptrdiff_t, size_t
#include <ostream>
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, int pointDimension);
+ QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c);
QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c);
- explicit QhullPoints(QhullQh *qh) : point_first(0), point_end(0), qh_qh(qh), point_dimension(qh ? qh->hull_dim : 0) {}
- QhullPoints(QhullQh *qh, int pointDimension) : point_first(0), point_end(0), qh_qh(qh), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
- QhullPoints(QhullQh *qh, 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<QhullPoint> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullPoint> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
QhullPoint at(countT idx) const { /* point_first==0 caught by point_end assert */ coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p<point_end); return QhullPoint(qh_qh, point_dimension, p); }
QhullPoint back() const { return last(); }
ConstIterator begin() const { return ConstIterator(*this); }
Iterator begin() { return Iterator(*this); }
ConstIterator constBegin() const { return ConstIterator(*this); }
const coordT * constData() const { return point_first; }
- ConstIterator constEnd() const { return ConstIterator(qh_qh, point_end); }
+ ConstIterator constEnd() const { return ConstIterator(qh_qh, point_dimension, point_end); }
coordT * coordinates() const { return point_first; }
countT coordinateCount() const { return (countT)(point_end-point_first); } // WARN64
countT count() const { return (countT)size(); } // WARN64
coordT * data() { return point_first; }
const coordT * data() const { return point_first; }
- void defineAs(countT coordinatesCount, coordT *c) { QHULL_ASSERT((coordinatesCount>=0 && c!=0) || (c==0 && coordinatesCount==0)); point_first= c; point_end= c+coordinatesCount; }
+ void defineAs(int pointDimension, countT coordinatesCount, coordT *c) { QHULL_ASSERT(pointDimension>=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_end); }
- Iterator end() { return Iterator(qh_qh, point_end); }
+ 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
QhullPoint first() const { return QhullPoint(qh_qh, point_dimension, point_first); }
QhullPoint front() const { return first(); }
bool includesCoordinates(const coordT *c) const { return c>=point_first && c<point_end; }
- bool isEmpty() const { return point_end==point_first; }
+ bool isEmpty() const { return (point_end==point_first || point_dimension==0); }
QhullPoint last() const { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
bool operator==(const QhullPoints &other) const;
- bool operator!=(const QhullPoints &other) const { return !operator==(other); }
+ bool operator!=(const QhullPoints &other) const { return ! operator==(other); }
QhullPoint operator[](countT idx) const { return at(idx); }
QhullQh * qh() const { return qh_qh; }
+ void resetQhullQh(QhullQh *qqh);
void setDimension(int d) { point_dimension= d; }
- void setQhullQh(QhullQh *qh);
size_t size() const { return point_dimension ? (point_end-point_first)/point_dimension : 0; }
QhullPoint value(countT idx) const;
// Non-const since copy is an alias
QhullPoint value(countT idx, QhullPoint &defaultValue) const;
#//!\name Methods
bool contains(const QhullPoint &t) const;
countT count(const QhullPoint &t) const;
countT indexOf(const coordT *pointCoordinates) const;
countT indexOf(const coordT *pointCoordinates, int noThrow) const;
countT indexOf(const QhullPoint &t) const;
countT lastIndexOf(const QhullPoint &t) const;
//! Returns a subset of the points, not a copy
QhullPoints mid(countT idx, countT length= -1) const;
#//!\name QhullPoints::iterator
// Modeled on qvector.h and qlist.h
// before const_iterator for conversion with comparison operators
// See: QhullSet.h
class iterator : public QhullPoint {
public:
typedef std::random_access_iterator_tag iterator_category;
typedef QhullPoint value_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef ptrdiff_t difference_type;
explicit iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
+ iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
- iterator(QhullQh *qh, coordT *c): QhullPoint(qh, c) {}
- iterator(QhullQh *qh, int pointDimension, coordT *c): QhullPoint(qh, pointDimension, c) {}
+ iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
+ iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
iterator(const iterator &other): QhullPoint(*other) {}
iterator & operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; }
-
+
QhullPoint * operator->() { return this; }
// value instead of reference since advancePoint() modifies self
QhullPoint operator*() const { return *this; }
QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
- bool operator==(const iterator &o) const { 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 && point_dimension==o.point_dimension); }
bool operator!=(const iterator &o) const { return !operator==(o); }
- bool operator<(const iterator &o) const { return point_coordinates < o.point_coordinates; }
- bool operator<=(const iterator &o) const { return point_coordinates <= o.point_coordinates; }
- bool operator>(const iterator &o) const { return point_coordinates > o.point_coordinates; }
- bool operator>=(const iterator &o) const { 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; }
+ 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<const iterator &>(o).qh_qh); return point_coordinates==reinterpret_cast<const iterator &>(o).point_coordinates; }
+ bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return (point_coordinates==reinterpret_cast<const iterator &>(o).point_coordinates && point_dimension==reinterpret_cast<const iterator &>(o).point_dimension); }
bool operator!=(const QhullPoints::const_iterator &o) const { return !operator==(reinterpret_cast<const iterator &>(o)); }
bool operator<(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates < reinterpret_cast<const iterator &>(o).point_coordinates; }
bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates <= reinterpret_cast<const iterator &>(o).point_coordinates; }
bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates > reinterpret_cast<const iterator &>(o).point_coordinates; }
bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates >= reinterpret_cast<const iterator &>(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
+ //!\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 *qh, coordT *c): QhullPoint(qh, c) {}
- const_iterator(QhullQh *qh, int pointDimension, coordT *c): QhullPoint(qh, 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<const_iterator &>(o)); return *this; }
// value/non-const since advancePoint(1), etc. modifies self
QhullPoint operator*() const { return *this; }
QhullPoint * operator->() { return this; }
QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
- bool operator==(const const_iterator &o) const { return point_coordinates==o.point_coordinates; }
- bool operator!=(const const_iterator &o) const { return !operator==(o); }
- bool operator<(const const_iterator &o) const { return point_coordinates < o.point_coordinates; }
- bool operator<=(const const_iterator &o) const { return point_coordinates <= o.point_coordinates; }
- bool operator>(const const_iterator &o) const { return point_coordinates > o.point_coordinates; }
- bool operator>=(const const_iterator &o) const { 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 && 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 { return PrintPoints("", false, *this); }
PrintPoints print(const char *message) const { return PrintPoints(message, false, *this); }
PrintPoints printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); }
- //FIXUP remove message for print()?
};//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/libqhullcpp/QhullQh.cpp b/src/libqhullcpp/QhullQh.cpp
index 13022fd..c587c3c 100644
--- a/src/libqhullcpp/QhullQh.cpp
+++ b/src/libqhullcpp/QhullQh.cpp
@@ -1,223 +1,238 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullQh.cpp#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullQh.cpp#15 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
#include "QhullError.h"
#include "QhullQh.h"
#include "QhullStat.h"
-#include "Qhull.h"
+// #include "Qhull.h"
#include <sstream>
#include <iostream>
#include <stdarg.h>
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 {
-#//Global variables
+#//!\name Global variables
const double QhullQh::
default_factor_epsilon= 1.0;
-#//Constructor, destructor, etc.
+#//!\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)
-, useOutputStream(false)
+, use_output_stream(false)
{
- // NOerrors -- Does not call qh_errexit()
+ // NOerrors: TRY_QHULL_ not needed since these routines do not call qh_errexit()
qh_meminit(this, NULL);
- this->ISqhullQh= True;
- // NOerrors -- Does not call qh_errexit()
qh_initstatistics(this);
- // NOerrors -- Does not call qh_errexit()
- qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr);
+ qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr); // Initialize qhT
+ this->ISqhullQh= True;
}//QhullQh
QhullQh::
~QhullQh()
{
qh_freeqhull(this, qh_ALL); // sets qh.NOerrexit. Clears struct *qh_qh including run_id
}//~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
-#//Messaging
+#//!\name Messaging
void QhullQh::
appendQhullMessage(const string &s)
{
- if(output_stream && useOutputStream && this->USEstdout){
+ 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.logError();
+ 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 useOutputStream
+//! Updates use_output_stream
void QhullQh::
setOutputStream(ostream *os)
{
output_stream= os;
- useOutputStream= (os!=0);
+ use_output_stream= (os!=0);
}//setOutputStream
}//namespace orgQhull
/*-<a href="qh_qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf">-</a>
qh_fprintf(qhT *qh, fp, msgcode, format, list of args )
- FIXUP s_qhull_output vs. fp is ignored (replaces qh_fprintf() in userprintf_r.c)
+ 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){
fprintf(stderr, "QH10025 Qhull error: qh_fprintf called from a Qhull instance without QhullQh defined\n");
qh_exit(10025);
}
QhullQh *qhullQh= static_cast<QhullQh *>(qh);
va_start(args, fmt);
if(msgcode<MSG_OUTPUT || fp == qh_FILEstderr){
if(msgcode>=MSG_ERROR && msgcode<MSG_WARNING){
if(qhullQh->qhull_status<MSG_ERROR || qhullQh->qhull_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->useOutputStream){
+ 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/libqhullcpp/QhullQh.h b/src/libqhullcpp/QhullQh.h
index f7c2a6f..e47f7a4 100644
--- a/src/libqhullcpp/QhullQh.h
+++ b/src/libqhullcpp/QhullQh.h
@@ -1,111 +1,112 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullQh.h#14 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullQh.h#21 $$Change: 1930 $
+** $DateTime: 2015/07/12 15:15:42 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLQH_H
#define QHULLQH_H
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <string>
#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
-//! QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
-//! }
-//! qh->maybeThrowQhullMessage(QH_TRY_status);
+//! 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, "Already inside a QH_TRY_(). qh.NOerrexit is false"); \
+ 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)
+ 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)
+ 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
+#//!\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
+ 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
-#//!\name Attribute
-public:
- bool useOutputStream; //! Set if using outputStream
- // FIXUP QH11003 feasiblePoint useOutputStream as field or getter?
+ 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/libqhullcpp/QhullRidge.cpp b/src/libqhullcpp/QhullRidge.cpp
index 5f87208..468a2ab 100644
--- a/src/libqhullcpp/QhullRidge.cpp
+++ b/src/libqhullcpp/QhullRidge.cpp
@@ -1,110 +1,123 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullRidge.cpp#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullRidge.cpp#11 $$Change: 1835 $
+** $DateTime: 2015/02/16 22:32:04 $$Author: bbarber $
**
****************************************************************************/
#//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
#include "QhullSets.h"
#include "QhullVertex.h"
#include "QhullRidge.h"
#include "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;
- ridgeT *ridge= qh_nextridge3d(qh_qh, getRidgeT(), f.getFacetT(), &v);
+ // 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= qh_nextridge3d(qh_qh, 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());
+ 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)
{
- os << pr.print_message;
+ if(*pr.print_message){
+ os << pr.print_message << " ";
+ }else{
+ os << " - ";
+ }
QhullRidge r= *pr.ridge;
- os << " - r" << r.id();
+ 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/libqhullcpp/QhullRidge.h b/src/libqhullcpp/QhullRidge.h
index c19befa..3042ae8 100644
--- a/src/libqhullcpp/QhullRidge.h
+++ b/src/libqhullcpp/QhullRidge.h
@@ -1,113 +1,114 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullRidge.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullRidge.h#15 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLRIDGE_H
#define QHULLRIDGE_H
#include "QhullSet.h"
#include "QhullVertex.h"
#include "QhullVertexSet.h"
#include "QhullFacet.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
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<QhullRidge> QhullRidgeSet;
typedef QhullSetIterator<QhullRidge> 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;
- QhullQh * qh_qh;
+ 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 *qh) : qh_ridge(&s_empty_ridge), qh_qh(qh) {}
- QhullRidge(QhullQh *qh, ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge), qh_qh(qh) {}
+ 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>
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->hull_dim; }
+ int dimension() const { return ((qh_qh && qh_qh->hull_dim) ? qh_qh->hull_dim-1 : 0); }
ridgeT * getBaseT() const { return getRidgeT(); } //!< For QhullSet<QhullRidge>
ridgeT * getRidgeT() const { return qh_ridge; }
countT id() const { return qh_ridge->id; }
- bool isDefined() const { return qh_ridge != &s_empty_ridge; }
+ 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;
+ const char * print_message; //!< non-null message
PrintRidge(const char *message, const QhullRidge &r) : ridge(&r), print_message(message) {}
};//PrintRidge
- PrintRidge print(const char* s) const { return PrintRidge(s, *this); }
+ 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 &r);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge::PrintRidge &pr);
#endif // QHULLRIDGE_H
diff --git a/src/libqhullcpp/QhullSet.h b/src/libqhullcpp/QhullSet.h
index 351db92..023b1bb 100644
--- a/src/libqhullcpp/QhullSet.h
+++ b/src/libqhullcpp/QhullSet.h
@@ -1,453 +1,455 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullSet.h#16 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullSet.h#20 $$Change: 1931 $
+** $DateTime: 2015/07/12 21:29:14 $$Author: bbarber $
**
****************************************************************************/
#ifndef QhullSet_H
#define QhullSet_H
#include "QhullError.h"
#include "QhullQh.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
+#include <cstddef> // ptrdiff_t, size_t
#ifndef QHULL_NO_STL
#include <vector>
#endif
#ifdef QHULL_USES_QT
#include <QtCore/QList>
#endif
namespace orgQhull {
#//!\name Used here
class Qhull;
#//!\name Defined here
class QhullSetBase; //! Base class for QhullSet<T>
//! QhullSet<T> defined below
//! QhullSetIterator<T> defined below
//! \see QhullPointSet, QhullLinkedList<T>
-//! QhullSetBase is a wrapper for Qhull's setT of void* pointers
-//! \see libqhullr/qset.h
+//! 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 *qh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qh) {}
+ 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 && idx<qh_set->maxsize); 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<T> -- A read-only wrapper to Qhull's collection class, setT.
//! QhullSet is similar to STL's <vector> 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/qvector.h
template <typename T>
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<T>::iterator Iterator;
typedef typename QhullSet<T>::const_iterator ConstIterator;
#//!\name Constructors
QhullSet<T>(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
- QhullSet<T>(QhullQh *qh, setT *s) : QhullSetBase(qh, s) { }
+ QhullSet<T>(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<T>(const QhullSet<T> &other) : QhullSetBase(other) {}
QhullSet<T> & operator=(const QhullSet<T> &other) { QhullSetBase::operator=(other); return *this; }
~QhullSet<T>() {}
private:
//!Disable default constructor. See QhullSetBase
QhullSet<T>();
public:
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<T> toStdVector() const;
#endif
#ifdef QHULL_USES_QT
QList<typename T> 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<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
bool operator!=(const QhullSet<T> &other) const { return !operator==(other); }
#//!\name Element access
const T at(countT idx) const { return operator[](idx); }
T back() { return last(); }
T back() const { return last(); }
//! end element is NULL
- const typename typename T::base_type * constData() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
+ const typename T::base_type * constData() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
typename T::base_type * data() { return reinterpret_cast<typename T::base_type *>(beginPointer()); }
- typename T::base_type * data() const { return reinterpret_cast<typename T::base_type *>(beginPointer()); }
+ const typename T::base_type *data() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
typename T::base_type * endData() { return reinterpret_cast<typename T::base_type *>(endPointer()); }
- typename T::base_type * endData() const { return reinterpret_cast<typename T::base_type *>(endPointer()); }
+ const typename T::base_type * endData() const { return reinterpret_cast<const typename T::base_type *>(endPointer()); }
T first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
const T first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
T front() { return first(); }
const T front() const { return first(); }
T last() { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
const T last() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
// mid() not available. No setT constructor
T operator[](countT idx) { typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
const T operator[](countT idx) const { const typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
T second() { return operator[](1); }
const T second() const { 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<typename T::base_type *>(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; // 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 *qh, typename T::base_type *p) : i(p), qh_qh(qh) {}
+ 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; }
T operator*() const { return T(qh_qh, *i); }
//operator->() n/a, value-type
T operator[](countT idx) { 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<const iterator &>(o).i); }
bool operator!=(const const_iterator &o) const { return !operator==(o); }
//! Assumes same point set
countT operator-(const iterator &o) { 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<o.i; }
bool operator>=(const iterator &o) const { return !operator<(o); }
bool operator>(const const_iterator &o) const { return (i > reinterpret_cast<const iterator &>(o).i); }
bool operator<=(const const_iterator &o) const { return !operator>(o); }
bool operator<(const const_iterator &o) const { return (i < reinterpret_cast<const iterator &>(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:
- typename T::base_type * i; // First for debugger
+ const typename T::base_type * i; // 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 *qh, typename T::base_type * p) : i(p), qh_qh(qh) {}
+ 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; }
T operator*() const { return T(qh_qh, *i); }
T operator[](countT idx) { 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<o.i; }
bool operator>=(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 <typename T>
class QhullSetIterator {
#//!\name Subtypes
typedef typename QhullSet<T>::const_iterator const_iterator;
private:
#//!\name Fields
- typename T::base_type * i; // First for debugger
- typename T::base_type * begin_i; // must be initialized after i
- typename T::base_type * end_i;
+ const typename T::base_type * i; // 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<T>(const QhullSet<T> &s) : i(s.data()), begin_i(i), end_i(s.endData()), qh_qh(s.qh()) {}
QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i), qh_qh(o.qh_qh) {}
QhullSetIterator<T> &operator=(const QhullSetIterator<T> &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 { typename T::base_type *p = i; return T(qh_qh, *--p); }
+ 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 <typename T>
std::vector<T> QhullSet<T>::
toStdVector() const
{
QhullSet<T>::const_iterator i= begin();
QhullSet<T>::const_iterator e= end();
std::vector<T> vs;
while(i!=e){
vs.push_back(*i++);
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
template <typename T>
QList<T> QhullSet<T>::
toQList() const
{
QhullSet<T>::const_iterator i= begin();
QhullSet<T>::const_iterator e= end();
QList<T> vs;
while(i!=e){
vs.append(*i++);
}
return vs;
}//toQList
#endif
#//!\name Element
template <typename T>
T QhullSet<T>::
value(countT idx) const
{
// Avoid call to qh_setsize() and assert in elementPointer()
- const T::base_type *p= reinterpret_cast<const T::base_type *>(&SETelem_(getSetT(), idx));
+ const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
return (idx>=0 && p<endData()) ? T(qh(), *p) : T(qh());
}//value
template <typename T>
T QhullSet<T>::
value(countT idx, const T &defaultValue) const
{
// Avoid call to qh_setsize() and assert in elementPointer()
const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
return (idx>=0 && p<endData() ? T(qh(), *p) : defaultValue);
}//value
#//!\name Search
template <typename T>
bool QhullSet<T>::
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 <typename T>
countT QhullSet<T>::
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<e){
if(*i==p){
n++;
}
i++;
}
return n;
}//count
template <typename T>
countT QhullSet<T>::
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 <typename T>
bool QhullSetIterator<T>::
findNext(const T &t)
{
typename T::base_type p= t.getBaseT();
while(i!=end_i){
if(*(++i)==p){
return true;
}
}
return false;
}//findNext
template <typename T>
bool QhullSetIterator<T>::
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 <typename T>
std::ostream &
operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
{
- typename T::base_type *i= qs.data();
- typename T::base_type *e= qs.endData();
+ 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/libqhullcpp/QhullStat.cpp b/src/libqhullcpp/QhullStat.cpp
index 27b502b..60d85fc 100644
--- a/src/libqhullcpp/QhullStat.cpp
+++ b/src/libqhullcpp/QhullStat.cpp
@@ -1,42 +1,42 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullStat.cpp#5 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullStat.cpp#6 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#//! QhullStat -- Qhull's global data structure, statT, as a C++ class
#include "QhullError.h"
#include "QhullStat.h"
#include <sstream>
#include <iostream>
using std::cerr;
using std::string;
using std::vector;
using std::ostream;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
-#//Constructor, destructor, etc.
+#//!\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/libqhullcpp/QhullStat.h b/src/libqhullcpp/QhullStat.h
index f78c285..e4688ac 100644
--- a/src/libqhullcpp/QhullStat.h
+++ b/src/libqhullcpp/QhullStat.h
@@ -1,52 +1,51 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullStat.h#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullStat.h#11 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLSTAT_H
#define QHULLSTAT_H
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <string>
#include <vector>
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
- static void clearStatistics();
#//!\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/libqhullcpp/QhullVertex.cpp b/src/libqhullcpp/QhullVertex.cpp
index c672373..c6c12de 100644
--- a/src/libqhullcpp/QhullVertex.cpp
+++ b/src/libqhullcpp/QhullVertex.cpp
@@ -1,106 +1,111 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertex.cpp#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertex.cpp#11 $$Change: 1816 $
+** $DateTime: 2015/01/21 22:51:49 $$Author: bbarber $
**
****************************************************************************/
#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class
#include "Qhull.h"
#include "QhullPoint.h"
#include "QhullFacetSet.h"
#include "QhullVertex.h"
#include "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();
- os << "- p" << p.id() << " (v" << v.id() << "): ";
+ 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/libqhullcpp/QhullVertex.h b/src/libqhullcpp/QhullVertex.h
index 41ae776..76cf877 100644
--- a/src/libqhullcpp/QhullVertex.h
+++ b/src/libqhullcpp/QhullVertex.h
@@ -1,105 +1,106 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertex.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertex.h#15 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLVERTEX_H
#define QHULLVERTEX_H
#include "QhullPoint.h"
#include "QhullLinkedList.h"
#include "QhullSet.h"
extern "C" {
- #include "libqhullr/qhull_ra.h"
+ #include "libqhull_r/qhull_ra.h"
}
#include <ostream>
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<QhullVertex> QhullVertexList;
typedef QhullLinkedListIterator<QhullVertex> 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;
- QhullQh * qh_qh;
+ 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 *qh) : qh_vertex(&s_empty_vertex), qh_qh(qh) {}
- QhullVertex(QhullQh *qh, vertexT *v) : qh_vertex(v ? v : &s_empty_vertex), qh_qh(qh) {}
+ 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>
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->hull_dim; }
+ int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
vertexT * getBaseT() const { return getVertexT(); } //!< For QhullSet<QhullVertex>
vertexT * getVertexT() const { return qh_vertex; }
countT id() const { return qh_vertex->id; }
- bool isDefined() const { return qh_vertex != &s_empty_vertex; }
+ 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;
+ 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/libqhullcpp/QhullVertexSet.cpp b/src/libqhullcpp/QhullVertexSet.cpp
index 270c300..0512fdd 100644
--- a/src/libqhullcpp/QhullVertexSet.cpp
+++ b/src/libqhullcpp/QhullVertexSet.cpp
@@ -1,145 +1,145 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertexSet.cpp#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertexSet.cpp#15 $$Change: 1835 $
+** $DateTime: 2015/02/16 22:32:04 $$Author: bbarber $
**
****************************************************************************/
#//! QhullVertexSet -- Qhull's linked Vertexs, as a C++ class
#include "QhullVertex.h"
#include "QhullVertexSet.h"
#include "QhullPoint.h"
#include "QhullRidge.h"
#include "QhullVertex.h"
#include "Qhull.h"
-#include "UsingLibQhull.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<QhullVertex>(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 *qh, facetT *facetlist, setT *facetset, bool allfacets)
-: QhullSet<QhullVertex>(qh, 0)
+QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets)
+: QhullSet<QhullVertex>(qqh, 0)
, qhsettemp_defined(false)
{
- QH_TRY_(qh){ // no object creation -- destructors skipped on longjmp()
- setT *vertices= qh_facetvertices(qh, facetlist, facetset, allfacets);
+ QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
+ setT *vertices= qh_facetvertices(qh(), facetlist, facetset, allfacets);
defineAs(vertices);
qhsettemp_defined= true;
}
- qh->maybeThrowQhullMessage(QH_TRY_status);
+ 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.
-//! If qhsettemp_defined, transfers ownership to destination, otherwise the set will be freed twice
-//! If qhsettemp_defined and passed by value, the set will be empty on return to caller
+//! Throws an error if qhsettemp_defined, otherwise have a double-free
+//!\todo Convert QhullVertexSet to a shared pointer with reference counting
QhullVertexSet::
-QhullVertexSet(QhullVertexSet &other)
+QhullVertexSet(const QhullVertexSet &other)
: QhullSet<QhullVertex>(other)
-, qhsettemp_defined(other.qhsettemp_defined)
+, qhsettemp_defined(false)
{
- other.qhsettemp_defined= false;
- other.forceEmpty();
+ 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.
-//! If qhsettemp_defined, transfers ownership to destination, otherwise the set will be freed twice
-//! If qhsettemp_defined and passed by value, the set will be empty on return to caller
-//! 'other' is not 'const' due to ownership transfer
+//! Throws an error if qhsettemp_defined, otherwise have a double-free
QhullVertexSet & QhullVertexSet::
-operator=(QhullVertexSet &other)
+operator=(const QhullVertexSet &other)
{
QhullSet<QhullVertex>::operator=(other);
- qhsettemp_defined= other.qhsettemp_defined;
- other.qhsettemp_defined= false;
- other.forceEmpty();
+ 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;
}//copy constructor
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
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullPoint;
using orgQhull::QhullVertex;
using orgQhull::QhullVertexSet;
using orgQhull::QhullVertexSetIterator;
-using orgQhull::UsingLibQhull;
//! Print Vertex identifiers to stream. Space prefix. From qh_printVertexheader [io_r.c]
ostream &
operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr)
{
- if(pr.print_message && *pr.print_message){
- os << pr.print_message;
- }
+ 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;
}//<<QhullVertexSet::PrintIdentifiers
//! Duplicate of printvertices [io_r.c]
ostream &
operator<<(ostream &os, const QhullVertexSet::PrintVertexSet &pr){
os << pr.print_message;
const QhullVertexSet *vs= pr.vertex_set;
QhullVertexSetIterator i= *vs;
while(i.hasNext()){
const QhullVertex v= i.next();
const QhullPoint p= v.point();
os << " p" << p.id() << "(v" << v.id() << ")";
}
os << endl;
return os;
}//<< PrintVertexSet
diff --git a/src/libqhullcpp/QhullVertexSet.h b/src/libqhullcpp/QhullVertexSet.h
index 46f8027..3980aea 100644
--- a/src/libqhullcpp/QhullVertexSet.h
+++ b/src/libqhullcpp/QhullVertexSet.h
@@ -1,79 +1,86 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertexSet.h#11 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/QhullVertexSet.h#14 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLVERTEXSET_H
#define QHULLVERTEXSET_H
#include "QhullSet.h"
+#include "QhullVertex.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
- class QhullVertex;
#//!\name Defined here
//! QhullVertexSet -- a set of Qhull Vertices, as a C++ class.
//! See Qhull
class QhullVertexSet;
typedef QhullSetIterator<QhullVertex> QhullVertexSetIterator;
class QhullVertexSet : public QhullSet<QhullVertex> {
private:
#//!\name Fields
bool qhsettemp_defined; //! Set was allocated with qh_settemp()
public:
#//!\name Constructor
QhullVertexSet(const Qhull &q, setT *s) : QhullSet<QhullVertex>(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 *qh, setT *s) : QhullSet<QhullVertex>(qh, s), qhsettemp_defined(false) {}
- QhullVertexSet(QhullQh *qh, facetT *facetlist, setT *facetset, bool allfacets);
- //Copy constructor copies pointer but not contents. Needed for return by value.
- QhullVertexSet(QhullVertexSet &other);
- QhullVertexSet & operator=(QhullVertexSet &other);
+ QhullVertexSet(QhullQh *qqh, setT *s) : QhullSet<QhullVertex>(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
+private: //!Default constructor disabled. Will implement allocation later
QhullVertexSet();
public:
#//!\name Destructor
void freeQhSetTemp();
+#//!\name Conversion
+#ifndef QHULL_NO_STL
+ std::vector<QhullVertex> toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<QhullVertex> toQList() const;
+#endif //QHULL_USES_QT
+
#//!\name IO
struct PrintVertexSet{
const QhullVertexSet *vertex_set;
- const char * print_message;
+ 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;
+ 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/libqhullcpp/RboxPoints.cpp b/src/libqhullcpp/RboxPoints.cpp
index 897d137..3870a07 100644
--- a/src/libqhullcpp/RboxPoints.cpp
+++ b/src/libqhullcpp/RboxPoints.cpp
@@ -1,221 +1,223 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/RboxPoints.cpp#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/RboxPoints.cpp#14 $$Change: 1951 $
+** $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
**
****************************************************************************/
#include "QhullError.h"
#include "RboxPoints.h"
#include <iostream>
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(0, "rbox")
+: 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(0, "rbox")
+: 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();
- setQhullQh(0);
+ 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()
{
- setQhullQh(new QhullQh);
+ QHULL_LIB_CHECK
+ 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<char*>(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
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
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<RboxPoints *>(qh->cpp_object);
va_start(args, fmt);
if(msgcode<MSG_OUTPUT){
char newMessage[MSG_MAXLEN];
// RoadError provides the message tag
vsnprintf(newMessage, sizeof(newMessage), fmt, args);
out->rbox_message += newMessage;
if(out->rbox_status<MSG_ERROR || out->rbox_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 countT vs. int
+ 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/libqhullcpp/RboxPoints.h b/src/libqhullcpp/RboxPoints.h
index 7f01229..78d86a8 100644
--- a/src/libqhullcpp/RboxPoints.h
+++ b/src/libqhullcpp/RboxPoints.h
@@ -1,71 +1,71 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/RboxPoints.h#12 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/RboxPoints.h#13 $$Change: 1914 $
+** $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
**
****************************************************************************/
#ifndef RBOXPOINTS_H
#define RBOXPOINTS_H
#include "QhullPoint.h"
#include "PointCoordinates.h"
extern "C" {
-#include "libqhullr/qhull_ra.h"
+#include "libqhull_r/qhull_ra.h"
}
#include <stdarg.h>
#include <string>
#include <vector>
#include <istream>
#include <ostream>
#include <sstream>
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
+ //! 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/libqhullcpp/RoadError.cpp b/src/libqhullcpp/RoadError.cpp
index e87c428..e9d9ae4 100644
--- a/src/libqhullcpp/RoadError.cpp
+++ b/src/libqhullcpp/RoadError.cpp
@@ -1,156 +1,158 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/RoadError.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/RoadError.cpp#4 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
#//! Do not throw RoadError's from destructors. Use e.logError() instead.
#include "RoadError.h"
#include <string>
#include <sstream>
#include <iostream>
using std::cerr;
using std::cout;
using std::string;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
-#//Class fields
+#//!\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;
-#//Constructor
+#//!\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=
-#//Virtual
+#//!\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
-#//Updates
+#//!\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::
-logError() const
+logErrorLastResort() const
{
global_log << what() << endl;
}//logError
}//namespace orgQhull
diff --git a/src/libqhullcpp/RoadError.h b/src/libqhullcpp/RoadError.h
index 7fbc260..01da3fa 100644
--- a/src/libqhullcpp/RoadError.h
+++ b/src/libqhullcpp/RoadError.h
@@ -1,86 +1,87 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/RoadError.h#5 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/RoadError.h#7 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#ifndef ROADERROR_H
#define ROADERROR_H
#include "RoadLogEvent.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
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
+ 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 isDefined() const { return log_event.isDefined(); }
+ 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 logError() const;
+ 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/libqhullcpp/RoadLogEvent.cpp b/src/libqhullcpp/RoadLogEvent.cpp
index b680498..dd82342 100644
--- a/src/libqhullcpp/RoadLogEvent.cpp
+++ b/src/libqhullcpp/RoadLogEvent.cpp
@@ -1,122 +1,122 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/RoadLogEvent.cpp#3 $$Change: 1810 $
-** $Date: 2015/01/17 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/RoadLogEvent.cpp#4 $$Change: 1868 $
+** $Date: 2015/03/26 $$Author: bbarber $
**
****************************************************************************/
#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
#include "RoadError.h"
#include <string>
#include <sstream>
#include <iostream>
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
-#//Class helpers (static)
+#//!\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/libqhullcpp/RoadLogEvent.h b/src/libqhullcpp/RoadLogEvent.h
index caf57e2..adf9dff 100644
--- a/src/libqhullcpp/RoadLogEvent.h
+++ b/src/libqhullcpp/RoadLogEvent.h
@@ -1,77 +1,77 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/RoadLogEvent.h#5 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/RoadLogEvent.h#6 $$Change: 1816 $
+** $DateTime: 2015/01/21 22:51:49 $$Author: bbarber $
**
****************************************************************************/
#ifndef ROADLOGEVENT_H
#define ROADLOGEVENT_H
#include <ostream>
#include <stdexcept>
#include <string>
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 isDefined() const { return format_string!=0; }
+ 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/libqhullcpp/UsingLibQhull.cpp b/src/libqhullcpp/UsingLibQhull.cpp
deleted file mode 100644
index d367eaf..0000000
--- a/src/libqhullcpp/UsingLibQhull.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/UsingLibQhull.cpp#8 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! UsingLibQhull -- Set up qhull C code from C++
-
-#include "Qhull.h"
-#include "UsingLibQhull.h"
-#include "QhullError.h"
-#include "QhullQh.h"
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//Class objects
-
-const double UsingLibQhull::
-DEFAULTdistanceEpsilon= 1e-15*FACTORepsilon; //! ~DISTround*FACTORepsilon for unit cube
-
-const double UsingLibQhull::
-DEFAULTangleEpsilon= 1e-15*FACTORepsilon; //! ~ANGLEround*FACTORepsilon for unit cube
-
- //! Global pointer to Qhull for qh_fprintf callback and QhullError
-Qhull *
-s_qhull_output= 0;
-
-double UsingLibQhull::
-s_angle_epsilon= 0;
-
-double UsingLibQhull::
-s_distance_epsilon= 0;
-
-//! For QhullPoint.id() w/o qhRunId. Initialized by Qhull
-const coordT *UsingLibQhull::
-s_points_begin= 0;
-const coordT *UsingLibQhull::
-s_points_end= 0;
-int UsingLibQhull::
-s_points_dimension= 0;
-
-int UsingLibQhull::
-s_vertex_dimension= 0; // FIXUP QH11023: s_vertex_dimension is required if dimension>15. Cannot store in QhullVertex
-
-bool UsingLibQhull::
-s_has_points= false;
-
-bool UsingLibQhull::
-s_has_angle_epsilon= false;
-
-bool UsingLibQhull::
-s_has_vertex_dimension= false;
-
-bool UsingLibQhull::
-s_has_distance_epsilon= false;
-
-bool UsingLibQhull::
-s_using_libqhull= false;
-
-#//Constructors
-
-//! Grabs global state (qh_qh, qh_qhstat, qhmem.tempstack)
-//! Follow immediately with setjmp(qh->errexit), otherwise errors in libqhull are not caught properly
-//! See qh_restore_qhull [global.c]
-UsingLibQhull::
-UsingLibQhull(Qhull *q)
-: my_qhull(q)
-, qh_exitcode(0)
-{
- checkUsingLibQhull();
- QhullQh *qhullqh= q->qhullQh();
- if(!qhullqh){
- throw QhullError(10014, "Qhull internal error: Qhull.qhullQh() not defined. initializeQhull() not called.");
- }
- s_qhull_output= q; // set s_qhull_output for qh_fprintf()
- qh->NOerrexit= False; // assumes setjmp called next
-}//UsingLibQhull qhull
-
-//! Same as UsingLibQhull but does not throw exceptions
-//! !defined() on failure. For use in destructors
-UsingLibQhull::
-UsingLibQhull(Qhull *q, int noThrow)
-: my_qhull(0) // Fail by default
-, qh_exitcode(0)
-{
- QHULL_UNUSED(noThrow);
-
- QhullQh *qhullqh= q->qhullQh();
- my_qhull= q;
- s_qhull_output= q; // set s_qhull_output for qh_fprintf()
- qh NOerrexit= False; // assumes setjmp called next
- }
-}//UsingLibQhull qhull noThrow
-
-//! Reuses current global state (qh_qh) from prior UsingQhull
-//! Errors if runId is not the same
-UsingLibQhull::
-UsingLibQhull(int qhRunId)
-: my_qhull(0)
-, qh_exitcode(0)
-{
- checkUsingLibQhull();
-#if qh_QHpointer
- if(!qh_qh || !qh_qhstat){
- throw QhullError(10024, "Qhull error: UsingLibQhull is not active (qh_qh %x or qh_qhstat is not defined)", 0,0,0.0, qh_qh);
- }
-#endif
- if(qh run_id!=qhRunId){
- throw QhullError(10036, "Qhull error: qhRunId %d != qh_qh.runId %d. Is another Qhull active?", qhRunId, qh run_id);
- }
- if(!s_qhull_output){
- throw QhullError(10037, "Qhull error: UsingLibQhull not active(s_qhull_output undefined). Invoke UsingLibQhull before this call");
- }
- if(s_qhull_output->qhull_run_id!=qhRunId){
- throw QhullError(10046, "Qhull error: qhRunId %d != s_qhull_output.runId %d. Is another Qhull active", qhRunId, s_qhull_output->qhull_run_id);
- }
- my_qhull= s_qhull_output;
- qh NOerrexit= False; // assumes setjmp called next
-}//UsingLibQhull runId
-
-//Leaves libqhull active for runId access
-UsingLibQhull::
-~UsingLibQhull()
-{
- QhullError e= checkRunId();
- if(e.isDefined()){
- e.logError();
- }else{
-#if qh_QHpointer
- if(qh_qh){
- qh NOerrexit= true;
- }
-#else
- qh NOerrexit= true;
-#endif
- }
- s_using_libqhull= false;
-}//~UsingLibQhull
-
-#//Class methods
-
-void UsingLibQhull::
-setGlobals()
-{
- if(s_qhull_output && s_qhull_output->initialized()){
- QhullQh *qqh= s_qhull_output->qhullQh();
- s_angle_epsilon= qqh->ANGLEround*FACTORepsilon;
- s_distance_epsilon= qqh->DISTround*FACTORepsilon;
- s_points_begin= qqh->first_point;
- s_points_dimension= qqh->hull_dim;
- s_points_end= s_points_begin+qqh->num_points*s_points_dimension;
- s_vertex_dimension= qqh->hull_dim;
- s_has_angle_epsilon= true;
- s_has_distance_epsilon= true;
- s_has_points= true;
- s_has_vertex_dimension= true;
- }else{
- throw QhullError(10058, "Qhull error: setGlobals can only be called for currentQhull(). Run qhull first.");
- }
- }//setGlobals
-
-void UsingLibQhull::
-unsetGlobals()
-{
- s_has_angle_epsilon= false;
- s_has_distance_epsilon= false;
- s_has_points= false;
- s_has_vertex_dimension= false;
-}//unsetGlobals
-
-#//Helpers
-
-}//namespace orgQhull
-
diff --git a/src/libqhullcpp/UsingLibQhull.h b/src/libqhullcpp/UsingLibQhull.h
deleted file mode 100644
index 538cc48..0000000
--- a/src/libqhullcpp/UsingLibQhull.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/UsingLibQhull.h#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef USINGlibqhull_H
-#define USINGlibqhull_H
-
-#include "QhullError.h"
-extern "C" {
-#include "libqhullr/qhull_ra.h"
-}
-
-namespace orgQhull {
-
-#//!\name Types
- //! UsingLibQhull -- Interface into libqhull and its 'qh' and 'qhstat' macros
- //! Always use with setjmp() for libqhull error handling.
-
-/*******************************
-
-UsingLibQhull is stack based, but as a call
-Qhull declarations are stack-based. But can't define a
-setjmp environment, since the target goes away. So must be UsingLibQhull, but can only have one
-setjmp at a time? Can embedded another Using as long as save/restore
-longjmp on exit.
-*/
- class UsingLibQhull;
-
- // Defined elsewhere
- class Qhull;
-
-class UsingLibQhull {
-
-private:
-#//!\name Fields
- Qhull * my_qhull;
- int qh_exitcode;
-
-#//!\name Class globals
- //! Global flags
- static bool s_using_libqhull; //! True if UsingLibQhull is in scope
-
- //! Use global values if s_has_... is set
- static bool s_has_angle_epsilon; //! True if s_angle_epsilon defined
- static bool s_has_distance_epsilon; //! True if s_distance_epsilon defined
- static bool s_has_points; //! If False (default), Qhull() runs setPointBase()
- static bool s_has_vertex_dimension; //! True if s_vertex_dimension defined
-
- //! Global values
- static double s_angle_epsilon; //! Epsilon for angle equality
- static double s_distance_epsilon; //! Epsilon for distance equality
- static const coordT *s_points_begin; //! For QhullPoint::id() w/o qhRunId.
- static const coordT *s_points_end; //! For QhullPoint::id() w/o qhRunId.
- static int s_points_dimension;
- static int s_vertex_dimension; //! Default dimension (e.g., if Vertex::dimension() >= 16)
-
-public:
-#//!\name Class constants
- static const int NOqhRunId= 0; //! qh_qh is not available
- static const int NOthrow= 1; //! Do not throw from maybeThrowQhullMessage
- static const int FACTORepsilon= 10; //!
- static const double DEFAULTdistanceEpsilon; //! ~DISTround*FACTORepsilon for unit cube
- static const double DEFAULTangleEpsilon; //! ~ANGLEround*FACTORepsilon for unit cube
-
-#//!\name Class members
- static void checkQhullMemoryEmpty();
- static double currentAngleEpsilon();
- static double currentDistanceEpsilon();
- static const coordT *currentPoints(int *dimension, const coordT **pointsEnd);
- static Qhull & currentQhull();
- static int currentVertexDimension();
- static double globalAngleEpsilon() { return s_has_angle_epsilon ? s_angle_epsilon : currentAngleEpsilon(); }
- static double globalDistanceEpsilon() { return s_has_distance_epsilon ? s_distance_epsilon : currentDistanceEpsilon(); }
- static double globalMachineEpsilon() { return REALepsilon; }
- static const coordT *globalPoints(int *dimension, const coordT **pointsEnd);
- static int globalVertexDimension() { return s_has_vertex_dimension ? s_vertex_dimension : currentVertexDimension(); }
- static bool hasPoints(); // inline would require Qhull.h
- static bool hasVertexDimension();
- static void setGlobalAngleEpsilon(double d) { s_angle_epsilon=d; s_has_angle_epsilon= true; }
- static void setGlobalDistanceEpsilon(double d) { s_distance_epsilon= d; s_has_distance_epsilon= true; }
- static void setGlobalPoints(int dimension, const coordT *pointsBegin, const coordT *pointsEnd) { s_points_dimension= dimension; s_points_begin= pointsBegin; s_points_end= pointsEnd; s_has_points= true; }
- static void setGlobalVertexDimension(int i) { s_vertex_dimension= i; s_has_vertex_dimension= true; }
- static void setGlobals();
- static void unsetGlobalAngleEpsilon() { s_has_angle_epsilon= false; }
- static void unsetGlobalDistanceEpsilon() { s_has_distance_epsilon= false; }
- static void unsetGlobalPoints() { s_has_points= false; }
- static void unsetGlobalVertexDimension() { s_has_vertex_dimension= false; }
- static void unsetGlobals();
-
-#//!\name Constructors
- UsingLibQhull(Qhull *p);
- UsingLibQhull(Qhull *p, int noThrow);
- UsingLibQhull(int qhRunId);
- ~UsingLibQhull();
-
-private: //! disable default constructor, copy constructor, and copy assignment
- UsingLibQhull();
- UsingLibQhull(const UsingLibQhull &);
- UsingLibQhull & operator=(const UsingLibQhull &);
-public:
-
-#//!\name Methods
-#//!\name Access
- bool defined() const { return my_qhull!=0; }
- void maybeThrowQhullMessage(int exitCode) const;
- void maybeThrowQhullMessage(int exitCode, int noThrow) const;
-
-#//!\name Helpers
-private:
- QhullError checkRunId() const;
- void checkUsingLibQhull() const;
-
-/***********************************
-You may use global variables in 'qh' after declaring UsingLibQhull. For example
-
- UsingLibQhull q(qhRunId);
- // NOerrors -- no calls that throw libqhull errors
- cout << "Delaunay Mode: " << qh DELAUNAY;
-
-To trap errors from libqhull, UsingLibQhull must be followed by
-
-UsingLibQhull q(qhRunId);
-int exitCode = setjmp(qh errexit);
-if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- calls to libqhull
-}
-q.maybeThrowQhullMessage(exitCode);
-
-The call to setjmp() can not be moved to a method. The stack must be preserved for error exits from libqhull.
-
-*/
-
-};//UsingLibQhull
-
-}//namespace orgQhull
-
-#endif // USINGlibqhull_H
diff --git a/src/libqhullcpp/libqhullcpp.pro b/src/libqhullcpp/libqhullcpp.pro
index 66abc06..79f2207 100644
--- a/src/libqhullcpp/libqhullcpp.pro
+++ b/src/libqhullcpp/libqhullcpp.pro
@@ -1,68 +1,70 @@
# -------------------------------------------------
# libqhullcpp.pro -- Qt project for Qhull cpp shared library
+#
+# It uses reentrant Qhull
# -------------------------------------------------
include(../qhull-warn.pri)
DESTDIR = ../../lib
TEMPLATE = lib
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/libqhullcpp/qhull_interface.cpp b/src/libqhullcpp/qhull_interface.cpp
deleted file mode 100644
index 7c81511..0000000
--- a/src/libqhullcpp/qhull_interface.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*<html><pre> -<a href="../libqhull/qh-user.htm"
- >-------------------------------</a><a name="TOP">-</a>
-*/
-
-#include <iostream.h>
-#include <conio.h>
-
-//--- Include qhull, so it works from with in a C++ source file
-//---
-//--- In MVC one cannot just do:
-//---
-//--- extern "C"
-//--- {
-//--- #include "qhull_a.h"
-//--- }
-//---
-//--- Because qhull_a.h includes math.h, which can not appear
-//--- inside a extern "C" declaration.
-//---
-//--- Maybe that why Numerical recipes in C avoid this problem, by removing
-//--- standard include headers from its header files and add them in the
-//--- respective source files instead.
-//---
-//--- [K. Erleben]
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <libqhull/qhulllib.h>
-#include <libqhull/mem.h>
-#include <libqhull/qset.h>
-#include <libqhull/geom.h>
-#include <libqhull/merge.h>
-#include <libqhull/poly.h>
-#include <libqhull/io.h>
-#include <libqhull/stat.h>
-#if defined(__cplusplus)
-}
-#endif
-
-/*********************************************************************/
-/* */
-/* */
-/* */
-/* */
-/*********************************************************************/
-
-void compute_convex_hull(void)
-{
- int dim; /* dimension of points */
- int numpoints; /* number of points */
- coordT *points; /* array of coordinates for each point */
- boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
- char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
- FILE *outfile= stdout; /* output from qh_produce_output()
- use NULL to skip qh_produce_output() */
- FILE *errfile= stderr; /* error messages from qhull code */
- int exitcode; /* 0 if no error from qhull */
- facetT *facet; /* set by FORALLfacets */
- int curlong, totlong; /* memory remaining after qh_memfreeshort */
-
- /* initialize dim, numpoints, points[], ismalloc here */
- exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
- flags, outfile, errfile);
- if (!exitcode) { /* if no error */
- /* 'qh facet_list' contains the convex hull */
- FORALLfacets {
- /* ... your code ... */
- }
- }
- qh_freeqhull(!qh_ALL);
- qh_memfreeshort(&curlong, &totlong);
- if (curlong || totlong)
- fprintf(errfile, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
- totlong, curlong);
-};
-
-/*********************************************************************/
-/* */
-/* */
-/* */
-/* */
-/*********************************************************************/
-
-void main()
-{
- cout << "Hello world" << endl;
-
- cout << "Press any key..." << endl;
-
- while (!_kbhit());
-
-};
diff --git a/src/libqhullcpp/qt-qhull.cpp b/src/libqhullcpp/qt-qhull.cpp
index 53573e4..3f38e36 100644
--- a/src/libqhullcpp/qt-qhull.cpp
+++ b/src/libqhullcpp/qt-qhull.cpp
@@ -1,130 +1,130 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullcpp/qt-qhull.cpp#8 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/libqhullcpp/qt-qhull.cpp#10 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
#include <QList>
-#include "RoadTest.h"
+#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 {
-#//Conversions
+#//!\name Conversions
QList<coordT> Coordinates::
toQList() const
{
CoordinatesIterator i(*this);
QList<coordT> cs;
while(i.hasNext()){
cs.append(i.next());
}
return cs;
}//toQList
QList<QhullFacet> QhullFacetList::
toQList() const
{
QhullLinkedListIterator<QhullFacet> i(*this);
QList<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.append(f);
}
}
return vs;
}//toQList
//! Same as PrintVertices
QList<QhullVertex> QhullFacetList::
vertices_toQList() const
{
QList<QhullVertex> 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<QhullFacet> QhullFacetSet::
toQList() const
{
QhullSetIterator<QhullFacet> i(*this);
QList<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.append(f);
}
}
return vs;
}//toQList
#ifdef QHULL_USES_QT
QList<coordT> QhullHyperplane::
toQList() const
{
QhullHyperplaneIterator i(*this);
QList<coordT> fs;
while(i.hasNext()){
fs.append(i.next());
}
fs.append(hyperplane_offset);
return fs;
}//toQList
#endif //QHULL_USES_QT
QList<coordT> QhullPoint::
toQList() const
{
QhullPointIterator i(*this);
QList<coordT> vs;
while(i.hasNext()){
vs.append(i.next());
}
return vs;
}//toQList
QList<QhullPoint> QhullPoints::
toQList() const
{
QhullPointsIterator i(*this);
QList<QhullPoint> vs;
while(i.hasNext()){
vs.append(i.next());
}
return vs;
}//toQList
/******
QList<QhullPoint> QhullPointSet::
toQList() const
{
QhullPointSetIterator i(*this);
QList<QhullPoint> vs;
while(i.hasNext()){
vs.append(i.next());
}
return vs;
}//toQList
*/
}//orgQhull
diff --git a/src/libqhullp/DEPRECATED.txt b/src/libqhullp/DEPRECATED.txt
deleted file mode 100644
index 8f20606..0000000
--- a/src/libqhullp/DEPRECATED.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-
-qhull/src/libqhullp
-
- This directory contains the deprecated qh_qhPOINTER configuration of qhull
-
- It will be maintained at least until January 2015.
-
- See qhull/src/libqhullr for the reentrant version of qhull
-
-
diff --git a/src/libqhullp/libqhullp.pro b/src/libqhullp/libqhullp.pro
deleted file mode 100644
index 38c6305..0000000
--- a/src/libqhullp/libqhullp.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-# -------------------------------------------------
-# libqhullp.pro -- Qt project for Qhull shared library with qh_QHpointer
-# Built with qh_QHpointer=1
-# -------------------------------------------------
-
-include(../qhull-warn.pri)
-
-DESTDIR = ../../lib
-DLLDESTDIR = ../../bin
-TEMPLATE = lib
-CONFIG += shared warn_on
-CONFIG -= qt
-
-build_pass:CONFIG(debug, debug|release):{
- TARGET = qhull_pd
- OBJECTS_DIR = Debug
-}else:build_pass:CONFIG(release, debug|release):{
- TARGET = qhull_p
- OBJECTS_DIR = Release
-}
-win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
-win32-msvc* : DEF_FILE += ../../src/libqhullp/qhull_p-exports.def
-
-DEFINES += qh_QHpointer # libqhull/user.h
-
-include(../qhull-libqhull-src.pri)
diff --git a/src/libqhullpcpp/Coordinates.cpp b/src/libqhullpcpp/Coordinates.cpp
deleted file mode 100644
index 008b1ab..0000000
--- a/src/libqhullpcpp/Coordinates.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/Coordinates.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "functionObjects.h"
-#include "QhullError.h"
-#include "Coordinates.h"
-
-#include <iostream>
-#include <iterator>
-#include <algorithm>
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//! Coordinates -- vector of coordT (normally double)
-
-#//Element access
-
-// Inefficient without result-value-optimization or implicitly shared object
-Coordinates Coordinates::
-mid(int idx, int length) const
-{
- int 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(int idx, const coordT &defaultValue) const
-{
- return ((idx < 0 || idx >= count()) ? defaultValue : (*this)[idx]);
-}//value
-
-#//Operator
-
-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+=
-
-#//Read-write
-
-coordT Coordinates::
-takeAt(int idx)
-{
- coordT c= at(idx);
- erase(begin()+idx);
- return c;
-}//takeAt
-
-coordT Coordinates::
-takeLast()
-{
- coordT c= last();
- removeLast();
- return c;
-}//takeLast
-
-void Coordinates::
-swap(int idx, int other)
-{
- coordT c= at(idx);
- at(idx)= at(other);
- at(other)= c;
-}//swap
-
-#//Search
-
-bool Coordinates::
-contains(const coordT &t) const
-{
- CoordinatesIterator i(*this);
- return i.findNext(t);
-}//contains
-
-int Coordinates::
-count(const coordT &t) const
-{
- CoordinatesIterator i(*this);
- int result= 0;
- while(i.findNext(t)){
- ++result;
- }
- return result;
-}//count
-
-int Coordinates::
-indexOf(const coordT &t, int from) const
-{
- if(from<0){
- from += count();
- if(from<0){
- from= 0;
- }
- }
- if(from<count()){
- const_iterator i= begin()+from;
- while(i!=constEnd()){
- if(*i==t){
- return (static_cast<int>(i-begin())); // WARN64
- }
- ++i;
- }
- }
- return -1;
-}//indexOf
-
-int Coordinates::
-lastIndexOf(const coordT &t, int 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<int>(i-begin())); // WARN64
- }
- }
- }
- return -1;
-}//lastIndexOf
-
-void Coordinates::
-removeAll(const coordT &t)
-{
- MutableCoordinatesIterator i(*this);
- while(i.findNext(t)){
- i.remove();
- }
-}//removeAll
-
-}//namespace orgQhull
-
-#//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(int i=cs.count(); i--; ){
- os << *c++ << " ";
- }
- return os;
-}//operator<<
-
diff --git a/src/libqhullpcpp/Coordinates.h b/src/libqhullpcpp/Coordinates.h
deleted file mode 100644
index a8923eb..0000000
--- a/src/libqhullpcpp/Coordinates.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/Coordinates.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHCOORDINATES_H
-#define QHCOORDINATES_H
-
-#include "QhullError.h"
-#include "QhullIterator.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-
-#include <cstddef> // ptrdiff_t, size_t
-#include <ostream>
-#include <vector>
-
-namespace orgQhull {
-
-#//!\name Types
- //! an allocated vector of point coordinates
- //! Used by PointCoordinates for RboxPoints
- //! A QhullPoint refers to previously allocated coordinates
- class Coordinates;
- class MutableCoordinatesIterator;
-
-
-class Coordinates {
-
-private:
-#//!\name Fields
- std::vector<coordT> 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 int size_type;
-
-#//!\name Construct
- Coordinates() {};
- explicit Coordinates(const std::vector<coordT> &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<coordT> &other) { coordinate_array= other; return *this; }
- ~Coordinates() {}
-
-#//!\name Conversion
-
- coordT * data() { return isEmpty() ? 0 : &at(0); }
- const coordT * data() const { return const_cast<const pointT*>(isEmpty() ? 0 : &at(0)); }
-
-#ifndef QHULL_NO_STL
- std::vector<coordT> toStdVector() const { return coordinate_array; }
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- QList<coordT> toQList() const;
-#endif //QHULL_USES_QT
-
-#//!\name GetSet
- int count() const { return static_cast<int>(size()); }
- bool empty() const { return coordinate_array.empty(); }
- bool isEmpty() const { return 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(int idx) { return coordinate_array.at(idx); }
- const coordT & at(int 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(int idx, int length= -1) const;
- coordT & operator[](int idx) { return coordinate_array.operator[](idx); }
- const coordT & operator[](int idx) const { return coordinate_array.operator[](idx); }
- coordT value(int 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 Read-only
- Coordinates operator+(const Coordinates &other) const;
-
-#//!\name Modify
- 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(int 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(int from, int 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(int idx) { erase(begin()+idx); }
- void removeFirst() { erase(begin()); }
- void removeLast() { erase(--end()); }
- void replace(int idx, const coordT &c) { (*this)[idx]= c; }
- void reserve(int i) { coordinate_array.reserve(i); }
- void swap(int idx, int other);
- coordT takeAt(int idx);
- coordT takeFirst() { return takeAt(0); }
- coordT takeLast();
-
-#//!\name Search
- bool contains(const coordT &t) const;
- int count(const coordT &t) const;
- int indexOf(const coordT &t, int from = 0) const;
- int lastIndexOf(const coordT &t, int 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
- class iterator {
-
- private:
- std::vector<coordT>::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<coordT>::iterator &vi) { i= vi; }
- iterator & operator=(const iterator &other) { i= other.i; return *this; }
- std::vector<coordT>::iterator &base() { return i; }
- // No operator-> for base types
- coordT & operator*() const { return *i; }
- coordT & operator[](int 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<other.i; }
- 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>=other.i; }
- // reinterpret_cast to break circular dependency
- bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast<const iterator &>(other); }
- bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast<const iterator &>(other); }
- bool operator<(const Coordinates::const_iterator &other) const { return *this<reinterpret_cast<const iterator &>(other); }
- bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast<const iterator &>(other); }
- bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast<const iterator &>(other); }
- bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast<const iterator &>(other); }
-
- iterator operator++() { return iterator(++i); } //FIXUP QH11012 Should return reference, but get reference to temporary
- iterator operator++(int) { return iterator(i++); }
- iterator operator--() { return iterator(--i); }
- iterator operator--(int) { return iterator(i--); }
- iterator operator+=(int idx) { return iterator(i += idx); }
- iterator operator-=(int idx) { return iterator(i -= idx); }
- iterator operator+(int idx) const { return iterator(i+idx); }
- iterator operator-(int 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<coordT>::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(iterator o) : i(o.i) {}
- explicit const_iterator(const std::vector<coordT>::const_iterator &vi) { i= vi; }
- const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
- // No operator-> for base types
- // No reference to a base type for () and []
- const coordT & operator*() const { return *i; }
- const coordT & operator[](int 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<other.i; }
- 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>=other.i; }
-
- const_iterator operator++() { return const_iterator(++i); } //FIXUP QH11014 -- too much copying
- const_iterator operator++(int) { return const_iterator(i++); }
- const_iterator operator--() { return const_iterator(--i); }
- const_iterator operator--(int) { return const_iterator(i--); }
- const_iterator operator+=(int idx) { return const_iterator(i += idx); }
- const_iterator operator-=(int idx) { return const_iterator(i -= idx); }
- const_iterator operator+(int idx) const { return const_iterator(i+idx); }
- const_iterator operator-(int 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;
- const Coordinates *c;
- const_iterator i;
- public:
- inline CoordinatesIterator(const Coordinates &container)
- : c(&container), i(c->constBegin()) {}
- inline CoordinatesIterator &operator=(const Coordinates &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 coordT &next() { return *i++; }
- inline const coordT &peekNext() const { return *i; }
- inline bool hasPrevious() const { return i != c->constBegin(); }
- inline const coordT &previous() { return *--i; }
- inline const coordT &peekPrevious() const { const_iterator p = i; return *--p; }
- inline bool findNext(const coordT &t)
- { while (i != c->constEnd()) if (*i++ == t) return true; return false; }
- inline bool findPrevious(const coordT &t)
- { while (i != c->constBegin()) if (*(--i) == t) return true;
- return false; }
-};//CoordinatesIterator
-
-//class MutableCoordinatesIterator
-//QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
-class MutableCoordinatesIterator
-{
- typedef Coordinates::iterator iterator;
- typedef Coordinates::const_iterator const_iterator;
- Coordinates *c;
- iterator i, n;
- inline bool item_exists() const { return const_iterator(n) != c->constEnd(); }
- public:
- inline MutableCoordinatesIterator(Coordinates &container)
- : c(&container)
- { i = c->begin(); n = c->end(); }
- inline ~MutableCoordinatesIterator()
- {}
- inline MutableCoordinatesIterator &operator=(Coordinates &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 coordT &next() { n = i++; return *n; }
- inline coordT &peekNext() const { return *i; }
- inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); }
- inline coordT &previous() { n = --i; return *n; }
- inline coordT &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 coordT &t) const { if (c->constEnd() != const_iterator(n)) *n = t; }
- inline coordT &value() { QHULL_ASSERT(item_exists()); return *n; }
- inline const coordT &value() const { QHULL_ASSERT(item_exists()); return *n; }
- inline void insert(const coordT &t) { n = i = c->insert(i, t); ++i; }
- inline bool findNext(const coordT &t)
- { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; }
- inline bool findPrevious(const coordT &t)
- { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true;
- n = c->end(); return false; }
-};//MutableCoordinatesIterator
-
-
-}//namespace orgQhull
-
-#//!\name Global
-
-std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c);
-
-#endif // QHCOORDINATES_H
diff --git a/src/libqhullpcpp/DEPRECATED.txt b/src/libqhullpcpp/DEPRECATED.txt
deleted file mode 100644
index c13770f..0000000
--- a/src/libqhullpcpp/DEPRECATED.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-qhull/src/libqhullpcpp
-
- This directory contains the deprecated cpp classes based on libqhullp.
-
- It will be maintained until January 2015.
-
- See qhull/src/libqhullcpp for the new cpp classes.
-
diff --git a/src/libqhullpcpp/PointCoordinates.cpp b/src/libqhullpcpp/PointCoordinates.cpp
deleted file mode 100644
index e671db4..0000000
--- a/src/libqhullpcpp/PointCoordinates.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/PointCoordinates.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "QhullError.h"
-#include "QhullPoint.h"
-#include "PointCoordinates.h"
-
-#include <iterator>
-#include <iostream>
-
-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
-
-#//Construct
-PointCoordinates::
-PointCoordinates()
-: QhullPoints()
-, point_coordinates()
-, point_comment()
-{
- makeValid();
-}
-
-#//Construct
-PointCoordinates::
-PointCoordinates(int pointDimension)
-: QhullPoints(pointDimension)
-, point_coordinates()
-, point_comment()
-{
- makeValid();
-}
-
-PointCoordinates::
-PointCoordinates(const std::string &aComment)
-: QhullPoints()
-, point_coordinates()
-, point_comment(aComment)
-{
- makeValid();
-}
-
-PointCoordinates::
-PointCoordinates(int pointDimension, const std::string &aComment)
-: QhullPoints(pointDimension)
-, point_coordinates()
-, point_comment(aComment)
-{
- makeValid();
-}
-
-PointCoordinates::
-PointCoordinates(int pointDimension, const std::string &aComment, int coordinatesCount, const coordT *c)
-: QhullPoints(pointDimension)
-, point_coordinates()
-, point_comment(aComment)
-{
- append(coordinatesCount, c);
-}
-
-PointCoordinates::
-PointCoordinates(const PointCoordinates &other)
-: QhullPoints(other)
-, point_coordinates(other.point_coordinates)
-, point_comment(other.point_comment)
-{
- makeValid();
-}
-
-PointCoordinates & PointCoordinates::
-operator=(const PointCoordinates &other)
-{
- QhullPoints::operator=(other);
- point_coordinates= other.point_coordinates;
- point_comment= other.point_comment;
- makeValid();
- return *this;
-}//operator=
-
-PointCoordinates::
-~PointCoordinates()
-{ }
-
-#//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
-
-//#Foreach
-
-Coordinates::ConstIterator PointCoordinates::
-beginCoordinates(int pointIndex) const
-{
- return point_coordinates.begin()+indexOffset(pointIndex);
-}
-
-Coordinates::Iterator PointCoordinates::
-beginCoordinates(int pointIndex)
-{
- return point_coordinates.begin()+indexOffset(pointIndex);
-}
-
-#//Modify
-
-void PointCoordinates::
-append(int 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] && point_comment.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());
- }
- }
- point_comment += s;
-}//appendComment
-
-//! Read PointCoordinates from istream. First two numbers are dimension and count. A non-digit starts a rboxCommand.
-//! Overwrites point_comment. See qh_readpoints [io.c]
-void PointCoordinates::
-appendPoints(istream &in)
-{
- int inDimension, 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, point_comment);
- 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, point_comment);
- in >> ws;
- }
- if(inCount<inDimension){ // Count may precede dimension
- std::swap(inCount, inDimension);
- }
- setDimension(inDimension);
- reserveCoordinates(inCount*inDimension);
- int coordinatesCount= 0;
- while(!in.eof()){
- realT p;
- in >> 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(int newCoordinates)
-{
- // vector::reserve is not const
- point_coordinates.reserve((int)point_coordinates.size()+newCoordinates); // WARN64
- makeValid();
-}//reserveCoordinates
-
-#//Helpers
-
-int PointCoordinates::
-indexOffset(int i) const {
- int n= i*dimension();
- int 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
-
-#//Global functions
-
-using std::endl;
-using std::ostream;
-
-using orgQhull::Coordinates;
-using orgQhull::PointCoordinates;
-
-ostream&
-operator<<(ostream &os, const PointCoordinates &p)
-{
- p.checkValid();
- int 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(int i=0; i<count; i++){
- for(int j=0; j<dimension; j++){
- os << *c++ << " ";
- }
- os << endl;
- }
- return os;
-}//operator<<
-
diff --git a/src/libqhullpcpp/PointCoordinates.h b/src/libqhullpcpp/PointCoordinates.h
deleted file mode 100644
index 354c5fa..0000000
--- a/src/libqhullpcpp/PointCoordinates.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/PointCoordinates.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHPOINTCOORDINATES_H
-#define QHPOINTCOORDINATES_H
-
-#include "QhullPoints.h"
-#include "Coordinates.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-#include <vector>
-
-namespace orgQhull {
-
-#//!\name Types
- //! Zero or more points with Coordinates, count, and dimension
- class PointCoordinates;
-
-class PointCoordinates : public QhullPoints {
-
-private:
-#//!\name Fields
- Coordinates point_coordinates; //! array of point coordinates
- //! may have extraCoordinates()
- std::string point_comment; //! Comment describing PointCoordinates
-
-public:
-#//!\name Construct
- PointCoordinates();
- explicit PointCoordinates(int pointDimension);
- explicit PointCoordinates(const std::string &aComment);
- PointCoordinates(int pointDimension, const std::string &aComment);
- PointCoordinates(int pointDimension, const std::string &aComment, int coordinatesCount, const coordT *c); // may be invalid
- //! Use append() and appendPoints() for Coordinates and vector<coordT>
- 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<coordT> &otherCoordinates) { if(!otherCoordinates.empty()){ append((int)otherCoordinates.size(), &otherCoordinates[0]); } }
- std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); }
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- void append(const QList<coordT> &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
- QList<coordT> 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 point_comment; }
- void makeValid() { defineAs(point_coordinates.count(), point_coordinates.data()); }
- const Coordinates & getCoordinates() const { return point_coordinates; }
- void setComment(const std::string &s) { point_comment= s; }
- void setDimension(int i);
-
-private:
- void defineAs(int coordinatesCount, coordT *c) { QhullPoints::defineAs(coordinatesCount, c); }
- //! defineAs() otherwise disabled
-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(int pointIndex) const;
- Coordinates::Iterator beginCoordinates(int 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 Read-only
- PointCoordinates operator+(const PointCoordinates &other) const;
-
-#//!\name Modify
- //FIXUP QH11001: Add clear() and other modify operators from Coordinates.h. Include QhullPoint::operator=()
- void append(int 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(int 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;
- const PointCoordinates *c;
- const_iterator i;
- public:
- inline PointCoordinatesIterator(const PointCoordinates &container)
- : c(&container), i(c->constBegin()) {}
- inline PointCoordinatesIterator &operator=(const PointCoordinates &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 QhullPoint next() { return *i++; }
- inline const QhullPoint peekNext() const { return *i; }
- inline bool hasPrevious() const { return i != c->constBegin(); }
- inline const QhullPoint previous() { return *--i; }
- inline const QhullPoint peekPrevious() const { const_iterator p = i; return *--p; }
- inline bool findNext(const QhullPoint &t)
- { while (i != c->constEnd()) if (*i++ == t) return true; return false; }
- inline 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/libqhullpcpp/Qhull.cpp b/src/libqhullpcpp/Qhull.cpp
deleted file mode 100644
index 9b160cd..0000000
--- a/src/libqhullpcpp/Qhull.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/Qhull.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! Qhull -- invoke qhull from C++
-#//! Compile libqhull and Qhull together due to use of setjmp/longjmp()
-
-#include "QhullError.h"
-#include "UsingLibQhull.h"
-#include "RboxPoints.h"
-#include "QhullQh.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "Qhull.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <iostream>
-
-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 {
-
-#//Global variables
-
-char s_unsupported_options[]=" Fd TI ";
-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 ";
-
-#//Constructor, destructor, etc.
-Qhull::
-Qhull()
-: qhull_qh(0)
-, qhull_run_id(UsingLibQhull::NOqhRunId)
-, origin_point()
-, qhull_status(qh_ERRnone)
-, qhull_dimension(0)
-, run_called(false)
-, qh_active(false)
-, qhull_message()
-, error_stream(0)
-, output_stream(0)
-, feasiblePoint()
-, useOutputStream(false)
-{
- allocateQhullQh();
-}//Qhull
-
-Qhull::
-Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
-: qhull_qh(0)
-, qhull_run_id(UsingLibQhull::NOqhRunId)
-, origin_point()
-, qhull_status(qh_ERRnone)
-, qhull_dimension(0)
-, run_called(false)
-, qh_active(false)
-, qhull_message()
-, error_stream(0)
-, output_stream(0)
-, feasiblePoint()
-, useOutputStream(false)
-{
- allocateQhullQh();
- runQhull(rboxPoints, qhullCommand2);
-}//Qhull rbox
-
-Qhull::
-Qhull(const char *rboxCommand2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
-: qhull_qh(0)
-, qhull_run_id(UsingLibQhull::NOqhRunId)
-, origin_point()
-, qhull_status(qh_ERRnone)
-, qhull_dimension(0)
-, run_called(false)
-, qh_active(false)
-, qhull_message()
-, error_stream(0)
-, output_stream(0)
-, feasiblePoint()
-, useOutputStream(false)
-{
- allocateQhullQh();
- runQhull(rboxCommand2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
-}//Qhull points
-
-Qhull::
-Qhull(const Qhull &other)
-: qhull_qh(0)
-, qhull_run_id(UsingLibQhull::NOqhRunId)
-, origin_point()
-, qhull_status(qh_ERRnone)
-, qhull_dimension(0)
-, run_called(false)
-, qh_active(false)
-, qhull_message(other.qhull_message)
-, error_stream(other.error_stream)
-, output_stream(other.output_stream)
-, feasiblePoint(other.feasiblePoint)
-, useOutputStream(other.useOutputStream)
-{
- if(other.initialized()){
- throw QhullError(10069, "Qhull error: can not use Qhull copy constructor if initialized() is true");
- }
- allocateQhullQh();
-}//copy constructor
-
-Qhull & Qhull::
-operator=(const Qhull &other)
-{
- if(other.initialized() || initialized()){
- throw QhullError(10070, "Qhull error: can not use Qhull copy assignment if initialized() is true");
- }
- qhull_message= other.qhull_message;
- error_stream= other.error_stream;
- output_stream= other.output_stream;
- feasiblePoint= other.feasiblePoint;
- useOutputStream= other.useOutputStream;
- return *this;
-}//copy constructor
-
-void Qhull::
-allocateQhullQh()
-{
- #if qh_QHpointer
- qhull_qh= new QhullQh;
- qhull_qh->old_qhstat= qh_qhstat;
- qhull_qh->old_tempstack= qhmem.tempstack;
- qh_qh= 0;
- qh_qhstat= 0;
- #else
- qhull_qh= new (&qh_qh) QhullQh;
- qhull_qh->old_qhstat= &qh_qhstat;
- qhull_qh->old_tempstack= qhmem.tempstack;
- #endif
- qhmem.tempstack= 0;
- qhull_run_id= qhull_qh->run_id;
-}//allocateQhullQh
-
-Qhull::
-~Qhull() throw()
-{
- //! UsingLibQhull is required by ~QhullQh
- UsingLibQhull q(this, QhullError::NOthrow);
- if(q.defined()){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
-#if qh_QHpointer
- delete qhull_qh;
- // clears qhull_qh and qh_qh
- qh_qh= 0;
-#else
- qhull_qh->~QhullQh();
- qhull_qh= 0;
-#endif
- qhull_run_id= UsingLibQhull::NOqhRunId;
- // Except for cerr, does not throw errors
- if(hasQhullMessage()){
- cerr<< "\nQhull output at end\n"; //FIXUP QH11005: where should error and log messages go on ~Qhull?
- cerr<<qhullMessage();
- clearQhullMessage();
- }
- }
- maybeThrowQhullMessage(exitCode, QhullError::NOthrow);
- }
- s_qhull_output= 0; // Set by UsingLibQhull
-}//~Qhull
-
-#//Messaging
-
-void Qhull::
-appendQhullMessage(const string &s)
-{
- if(output_stream && useOutputStream && qh USEstdout){ // threading errors caught elsewhere
- *output_stream << s;
- }else if(error_stream){
- *error_stream << s;
- }else{
- qhull_message += s;
- }
-}//appendQhullMessage
-
-//! clearQhullMessage does not throw errors (~Qhull)
-void Qhull::
-clearQhullMessage()
-{
- qhull_status= qh_ERRnone;
- qhull_message.clear();
- RoadError::clearGlobalLog();
-}//clearQhullMessage
-
-//! hasQhullMessage does not throw errors (~Qhull)
-bool Qhull::
-hasQhullMessage() const
-{
- return (!qhull_message.empty() || qhull_status!=qh_ERRnone);
- //FIXUP QH11006 -- inconsistent usage with Rbox. hasRboxMessage just tests rbox_status. No appendRboxMessage()
-}
-
-//! qhullMessage does not throw errors (~Qhull)
-std::string Qhull::
-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 Qhull::
-qhullStatus() const
-{
- return qhull_status;
-}//qhullStatus
-
-void Qhull::
-setErrorStream(ostream *os)
-{
- error_stream= os;
-}//setErrorStream
-
-//! Updates useOutputStream
-void Qhull::
-setOutputStream(ostream *os)
-{
- output_stream= os;
- useOutputStream= (os!=0);
-}//setOutputStream
-
-#//GetSet
-
-void Qhull::
-checkIfQhullInitialized()
-{
- if(!initialized()){ // qh_initqhull_buffers() not called
- throw QhullError(10023, "Qhull error: checkIfQhullInitialized failed. Call runQhull() first.");
- }
-}//checkIfQhullInitialized
-
-//! Setup global state (qh_qh, qh_qhstat, qhmem.tempstack)
-int Qhull::
-runId()
-{
- UsingLibQhull u(this);
- QHULL_UNUSED(u);
-
- return qhull_run_id;
-}//runId
-
-
-#//GetValue
-
-double Qhull::
-area(){
- checkIfQhullInitialized();
- UsingLibQhull q(this);
- if(!qh hasAreaVolume){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_getarea(qh facet_list);
- }
- maybeThrowQhullMessage(exitCode);
- }
- return qh totarea;
-}//area
-
-double Qhull::
-volume(){
- checkIfQhullInitialized();
- UsingLibQhull q(this);
- if(!qh hasAreaVolume){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_getarea(qh facet_list);
- }
- maybeThrowQhullMessage(exitCode);
- }
- return qh totvol;
-}//volume
-
-#//ForEach
-
-//! Define QhullVertex::neighborFacets().
-//! Automatically called if merging facets or computing the Voronoi diagram.
-//! Noop if called multiple times.
-void Qhull::
-defineVertexNeighborFacets(){
- checkIfQhullInitialized();
- UsingLibQhull q(this);
- if(!qh hasAreaVolume){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_vertexneighbors();
- }
- maybeThrowQhullMessage(exitCode);
- }
-}//defineVertexNeighborFacets
-
-QhullFacetList Qhull::
-facetList() const{
- return QhullFacetList(beginFacet(), endFacet());
-}//facetList
-
-QhullPoints Qhull::
-points() const
-{
- return QhullPoints(hullDimension(), qhull_qh->num_points*hullDimension(), qhull_qh->first_point);
-}//points
-
-QhullPointSet Qhull::
-otherPoints() const
-{
- return QhullPointSet(hullDimension(), qhull_qh->other_points);
-}//otherPoints
-
-//! Return vertices of the convex hull.
-QhullVertexList Qhull::
-vertexList() const{
- return QhullVertexList(beginVertex(), endVertex());
-}//vertexList
-
-#//Modify
-
-void Qhull::
-outputQhull()
-{
- checkIfQhullInitialized();
- UsingLibQhull q(this);
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_produce_output2();
- }
- maybeThrowQhullMessage(exitCode);
-}//outputQhull
-
-void Qhull::
-outputQhull(const char *outputflags)
-{
- checkIfQhullInitialized();
- UsingLibQhull q(this);
- string cmd(" "); // qh_checkflags skips first word
- cmd += outputflags;
- char *command= const_cast<char*>(cmd.c_str());
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_clear_outputflags();
- char *s = qh qhull_command + strlen(qh qhull_command) + 1; //space
- strncat(qh qhull_command, command, sizeof(qh qhull_command)-strlen(qh qhull_command)-1);
- qh_checkflags(command, s_not_output_options);
- qh_initflags(s);
- qh_initqhull_outputflags();
- if(qh KEEPminArea < REALmax/2
- || (0 != qh KEEParea + qh KEEPmerge + qh GOODvertex
- + qh GOODthreshold + qh GOODpoint + qh SPLITthresholds)){
- facetT *facet;
- qh ONLYgood= False;
- FORALLfacet_(qh facet_list) {
- facet->good= True;
- }
- qh_prepare_output();
- }
- qh_produce_output2();
- if(qh VERIFYoutput && !qh STOPpoint && !qh STOPcone){
- qh_check_points();
- }
- }
- maybeThrowQhullMessage(exitCode);
-}//outputQhull
-
-void Qhull::
-runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
-{
- runQhull(rboxPoints.comment().c_str(), rboxPoints.dimension(), rboxPoints.count(), &*rboxPoints.coordinates(), qhullCommand2);
-}//runQhull, RboxPoints
-
-//! points is a array of points, input sites ('d' or 'v'), or halfspaces with offset last ('H')
-//! Derived from qh_new_qhull [user.c]
-void Qhull::
-runQhull(const char *rboxCommand2, int pointDimension, int pointCount, const realT *rboxPoints, const char *qhullCommand2)
-{
- if(run_called){
- throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed.");
- }
- run_called= true;
- string s("qhull ");
- s += qhullCommand2;
- char *command= const_cast<char*>(s.c_str());
- UsingLibQhull q(this);
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_checkflags(command, s_unsupported_options);
- qh_initflags(command);
- *qh rbox_command= '\0';
- strncat( qh rbox_command, rboxCommand2, sizeof(qh rbox_command)-1);
- if(qh DELAUNAY){
- qh PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput()
- }
- pointT *newPoints= const_cast<pointT*>(rboxPoints);
- int newDimension= pointDimension;
- int newIsMalloc= False;
- if(qh HALFspace){
- --newDimension;
- initializeFeasiblePoint(newDimension);
- newPoints= qh_sethalfspace_all(pointDimension, pointCount, newPoints, qh feasible_point);
- newIsMalloc= True;
- }
- qh_init_B(newPoints, pointCount, newDimension, newIsMalloc);
- qhull_dimension= (qh DELAUNAY ? qh hull_dim - 1 : qh hull_dim);
- qh_qhull();
- qh_check_output();
- qh_prepare_output();
- if(qh VERIFYoutput && !qh STOPpoint && !qh STOPcone){
- qh_check_points();
- }
- }
- for(int k= qhull_dimension; k--; ){ // Do not move up (may throw)
- origin_point << 0.0;
- }
- maybeThrowQhullMessage(exitCode);
-}//runQhull
-
-#//Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
-
-void Qhull::
-initializeFeasiblePoint(int hulldim)
-{
- if(qh feasible_string){
- qh_setfeasible(hulldim);
- }else{
- if(feasiblePoint.empty()){
- qh_fprintf(qh ferr, 6209, "qhull error: missing feasible point for halfspace intersection. Use option 'Hn,n' or set qh.feasiblePoint\n");
- qh_errexit(qh_ERRmem, NULL, NULL);
- }
- if(feasiblePoint.size()!=(size_t)hulldim){
- qh_fprintf(qh ferr, 6210, "qhull error: dimension of feasiblePoint should be %d. It is %u", hulldim, feasiblePoint.size());
- qh_errexit(qh_ERRmem, NULL, NULL);
- }
- if (!(qh feasible_point= (coordT*)qh_malloc(hulldim * sizeof(coordT)))) {
- qh_fprintf(qh ferr, 6202, "qhull error: insufficient memory for feasible point\n");
- qh_errexit(qh_ERRmem, NULL, NULL);
- }
- coordT *t= qh feasible_point;
- // No qh_... routines after here -- longjmp() ignores destructor
- for(Coordinates::ConstIterator p=feasiblePoint.begin(); p<feasiblePoint.end(); p++){
- *t++= *p;
- }
- }
-}//initializeFeasiblePoint
-
-void Qhull::
-maybeThrowQhullMessage(int exitCode)
-{
- 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 Qhull::
-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.logError();
- }
-}//maybeThrowQhullMessage
-
-}//namespace orgQhull
-
-/*-<a href="qh-user.htm#TOC"
- >-------------------------------</a><a name="qh_fprintf">-</a>
-
- qh_fprintf(fp, msgcode, format, list of args )
- fp is ignored (replaces qh_fprintf() in userprintf.c)
- s_qhull_output == Qhull
-
-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(FILE *fp, int msgcode, const char *fmt, ... ) {
- va_list args;
-
- using namespace orgQhull;
-
- if(!s_qhull_output){
- fprintf(stderr, "QH10025 Qhull error: UsingLibQhull not declared prior to calling qh_...(). s_qhull_output==NULL.\n");
- qh_exit(10025);
- }
- Qhull *out= s_qhull_output;
- va_start(args, fmt);
- if(msgcode<MSG_OUTPUT || fp == qh_FILEstderr){
- if(msgcode>=MSG_ERROR && msgcode<MSG_WARNING){
- if(out->qhull_status<MSG_ERROR || out->qhull_status>=MSG_WARNING){
- out->qhull_status= msgcode;
- }
- }
- char newMessage[MSG_MAXLEN];
- // RoadError will add the message tag
- vsnprintf(newMessage, sizeof(newMessage), fmt, args);
- out->appendQhullMessage(newMessage);
- va_end(args);
- return;
- }
- if(out->output_stream && out->useOutputStream){
- char newMessage[MSG_MAXLEN];
- vsnprintf(newMessage, sizeof(newMessage), fmt, args);
- *out->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);
- out->appendQhullMessage(newMessage);
- va_end(args);
-} /* qh_fprintf */
-
diff --git a/src/libqhullpcpp/Qhull.h b/src/libqhullpcpp/Qhull.h
deleted file mode 100644
index 512aa25..0000000
--- a/src/libqhullpcpp/Qhull.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/Qhull.h#4 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLCPP_H
-#define QHULLCPP_H
-
-#include "QhullQh.h"
-#include "RboxPoints.h"
-#include "QhullLinkedList.h"
-#include "QhullPoint.h"
-#include "QhullPoints.h"
-#include "QhullVertex.h"
-#include "QhullFacet.h"
-
-#include <stdarg.h>
-#include <string>
-#include <vector>
-#include <sstream>
-#include <iostream>
-
-#if qh_QHpointer != 1
-#error qh_QHpointer is not set. Please set it in user.h or
-#error compile Qhull with -Dqh_QHpointer. The C++ classes
-#error require dynamic allocation for Qhulls global data
-#error structure qhT (QhullQh).
-#endif
-
-namespace orgQhull {
-
-/***
- Compile qhullcpp and libqhull with the same compiler. setjmp() and longjmp() must be the same.
-*/
-
-#//!\name Types
- //! Qhull -- run Qhull from C++
- class Qhull;
-
- //Defined elsewhere
- class QhullFacetList;
- class RboxPoints;
-
-class Qhull {
-
-private:
-#//!\name Members and friends
- QhullQh * qhull_qh; //! qh_qh for this instance
- int qhull_run_id; //! qh.run_id at initialization (catch multiple runs if !qh_QHpointer)
- Coordinates origin_point; //! origin for qhull_dimension. Set by runQhull()
- int qhull_status; //! qh_ERRnone if valid
- int qhull_dimension; //! Dimension of result (qh.hull_dim or one less for Delaunay/Voronoi)
- bool run_called; //! True at start of runQhull. Errors if call again.
- bool qh_active; //! True if global pointer qh_qh equals qhull_qh
- std::string qhull_message;
- std::ostream * error_stream; //! overrides errorMessage, use appendQhullMessage()
- std::ostream * output_stream; //! send output to stream
-
- friend void ::qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
- friend class UsingLibQhull;
-
-#//!\name Attribute
-public:
- Coordinates feasiblePoint; //! feasible point for half-space intersection
- bool useOutputStream; //! Set if using outputStream
- // FIXUP QH11003 feasiblePoint useOutputStream as field or getter?
-
-#//!\name constructor, assignment, destructor, invariant
- Qhull(); //! Qhull::runQhull() must be called next
- Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
- Qhull(const char *rboxCommand2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
- // Throws error if other.initialized(). Needed for return by value and parameter passing
- Qhull(const Qhull &other);
- // Throws error if initialized() or other.initialized(). Needed for vector<Qhull>
- Qhull & operator=(const Qhull &other);
- ~Qhull() throw();
-private:
- void allocateQhullQh();
-
-public:
-#//!\name !\name virtual methods
- //FIXUP QH11004 -- qh_memfree, etc. as virtual?
-
-#//!\name Messaging
- void appendQhullMessage(const std::string &s);
- void clearQhullMessage();
- std::string qhullMessage() const;
- bool hasQhullMessage() const;
- int qhullStatus() const;
- void setErrorStream(std::ostream *os);
- void setOutputStream(std::ostream *os);
-
-#//!\name GetSet
- void checkIfQhullInitialized();
- bool initialized() const { return qhull_dimension>0; }
- int dimension() const { return qhull_dimension; }
- int hullDimension() const { return qhullQh()->hull_dim; }
- // non-const due to QhullPoint
- QhullPoint origin() { QHULL_ASSERT(initialized()); return QhullPoint(dimension(), origin_point.data()); }
- QhullQh * qhullQh() const { return qhull_qh; };
- int runId(); // Modifies my_qhull
-
-#//!\name GetQh -- access to qhT (Qhull's global data structure)
- const char * qhullCommand() const { return qhull_qh->qhull_command; }
- const char * rboxCommand() const { return qhull_qh->rbox_command; }
- int facetCount() const { return qhull_qh->num_facets; }
- int vertexCount() const { return qhull_qh->num_vertices; }
-
-#//!\name GetValue
- double area();
- double volume();
-
-#//!\name ForEach
- QhullFacet beginFacet() const { return QhullFacet(qhull_qh->facet_list); }
- QhullVertex beginVertex() const { return QhullVertex(qhull_qh->vertex_list); }
- void defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram
- QhullFacet endFacet() const { return QhullFacet(qhull_qh->facet_tail); }
- QhullVertex endVertex() const { return QhullVertex(qhull_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 qhull_qh->first_point; }
- coordT * pointCoordinateEnd() const { return qhull_qh->first_point + qhull_qh->num_points*qhull_qh->hull_dim; }
- QhullVertexList vertexList() const;
-
-#//!\name Modify
- void outputQhull();
- void outputQhull(const char * outputflags);
- void runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
- void runQhull(const char *rboxCommand2, int pointDimension, int pointCount, const realT *rboxPoints, const char *qhullCommand2);
-
-private:
-#//!\name Helpers
- void initializeFeasiblePoint(int hulldim);
- void maybeThrowQhullMessage(int exitCode);
- void maybeThrowQhullMessage(int exitCode, int noThrow) throw();
-};//Qhull
-
-}//namespace orgQhull
-
-#endif // QHULLCPP_H
diff --git a/src/libqhullpcpp/QhullError.h b/src/libqhullpcpp/QhullError.h
deleted file mode 100644
index 757b146..0000000
--- a/src/libqhullpcpp/QhullError.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullError.h#4 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLERROR_H
-#define QHULLERROR_H
-
-#include "RoadError.h"
-// No dependencies on libqhull
-
-#include <assert.h>
-#include <stdexcept>
-#include <string>
-
-namespace orgQhull {
-
-#//!\name Types
- //! 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= 10073,
- NOthrow= 1 //! For flag to UsingLibQhull()
- };
-
-#//!\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
-
-#ifndef QHULL_1
- #define QHULL_ASSERT assert
-
-#endif
-
-}//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/libqhullpcpp/QhullFacet.cpp b/src/libqhullpcpp/QhullFacet.cpp
deleted file mode 100644
index 990f620..0000000
--- a/src/libqhullpcpp/QhullFacet.cpp
+++ /dev/null
@@ -1,524 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacet.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
-
-#include "QhullError.h"
-#include "QhullSet.h"
-#include "QhullPoint.h"
-#include "QhullPointSet.h"
-#include "QhullRidge.h"
-#include "QhullFacet.h"
-#include "QhullFacetSet.h"
-#include "QhullVertex.h"
-
-#include <ostream>
-
-using std::endl;
-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 {
-
-#//class statics
-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};
-
-#//GetSet
-
-int QhullFacet::
-dimension() const
-{
- if(qh_facet->ridges){
- setT *s= qh_facet->ridges;
- ridgeT *r= reinterpret_cast<ridgeT *>(SETfirst_(s));
- return r ? QhullSetBase::count(r->vertices)+1 : 0;
- }else{
- return QhullSetBase::count(qh_facet->vertices);
- }
-}//dimension
-
-//! Return voronoi center or facet centrum. Derived from qh_printcenter [io.c]
-//! printFormat=qh_PRINTtriangles if return centrum of a Delaunay facet
-//! Sets center if needed
-//! Code duplicated for PrintCenter and getCenter
-//! .empty() if none or qh_INFINITE
-QhullPoint QhullFacet::
-getCenter(int qhRunId, qh_PRINT printFormat)
-{
- UsingLibQhull q(qhRunId);
-
- if(qh CENTERtype==qh_ASvoronoi){
- if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh ATinfinity){
- if(!qh_facet->center){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_facet->center= qh_facetcenter(qh_facet->vertices);
- }
- q.maybeThrowQhullMessage(exitCode);
- }
- return QhullPoint(qh hull_dim-1, qh_facet->center);
- }
- }else if(qh CENTERtype==qh_AScentrum){
- volatile int numCoords= qh hull_dim;
- if(printFormat==qh_PRINTtriangles && qh DELAUNAY){
- numCoords--;
- }
- if(!qh_facet->center){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_facet->center= qh_getcentrum(getFacetT());
- }
- q.maybeThrowQhullMessage(exitCode);
- }
- return QhullPoint(numCoords, qh_facet->center);
- }
- return QhullPoint();
- }//getCenter
-
-//! Return innerplane clearly below the vertices
-//! from io.c[qh_PRINTinner]
-QhullHyperplane QhullFacet::
-innerplane(int qhRunId) const{
- UsingLibQhull q(qhRunId);
- realT inner;
- // Does not error
- qh_outerinner(const_cast<facetT *>(getFacetT()), NULL, &inner);
- QhullHyperplane h= hyperplane();
- h.setOffset(h.offset()-inner); //inner is negative
- return h;
-}//innerplane
-
-//! Return outerplane clearly above all points
-//! from io.c[qh_PRINTouter]
-QhullHyperplane QhullFacet::
-outerplane(int qhRunId) const{
- UsingLibQhull q(qhRunId);
- realT outer;
- // Does not error
- qh_outerinner(const_cast<facetT *>(getFacetT()), &outer, NULL);
- QhullHyperplane 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 qh_facet->f.triowner;
- }
- return 0; // FIXUP QH11009 Should false be the NULL facet or empty facet
-}//tricoplanarOwner
-
-QhullPoint QhullFacet::
-voronoiVertex(int qhRunId)
-{
- if(
-#if qh_QHpointer
- !qh_qh ||
-#endif
- qh CENTERtype!=qh_ASvoronoi){
- throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
- }
- return getCenter(qhRunId);
-}//voronoiVertex
-
-#//Value
-
-//! Disables tricoplanarOwner()
-double QhullFacet::
-facetArea(int qhRunId)
-{
- if(!qh_facet->isarea){
- UsingLibQhull q(qhRunId);
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_facet->f.area= qh_facetarea(qh_facet);
- qh_facet->isarea= True;
- }
- q.maybeThrowQhullMessage(exitCode);
- }
- return qh_facet->f.area;
-}//facetArea
-
-#//Foreach
-
-QhullPointSet QhullFacet::
-coplanarPoints() const
-{
- return QhullPointSet(dimension(), qh_facet->coplanarset);
-}//coplanarPoints
-
-QhullFacetSet QhullFacet::
-neighborFacets() const
-{
- return QhullFacetSet(qh_facet->neighbors);
-}//neighborFacets
-
-QhullPointSet QhullFacet::
-outsidePoints() const
-{
- return QhullPointSet(dimension(), qh_facet->outsideset);
-}//outsidePoints
-
-QhullRidgeSet QhullFacet::
-ridges() const
-{
- return QhullRidgeSet(qh_facet->ridges);
-}//ridges
-
-QhullVertexSet QhullFacet::
-vertices() const
-{
- return QhullVertexSet(qh_facet->vertices);
-}//vertices
-
-
-}//namespace orgQhull
-
-#//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;
-using orgQhull::UsingLibQhull;
-
-ostream &
-operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
-{
- 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(pr.run_id);
- if(!f.ridges().isEmpty()){
- os << f.printRidges(pr.run_id);
- }
- return os;
-}//operator<< PrintFacet
-
-//! Print Voronoi center or facet centrum to stream. Same as qh_printcenter [io.c]
-//! Code duplicated for PrintCenter and getCenter
-//! Sets center if needed
-ostream &
-operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
-{
- facetT *f= pr.facet->getFacetT();
- if(qh CENTERtype!=qh_ASvoronoi && qh CENTERtype!=qh_AScentrum){
- return os;
- }
- if (pr.message){
- os << pr.message;
- }
- int numCoords;
- if(qh CENTERtype==qh_ASvoronoi){
- numCoords= qh hull_dim-1;
- if(!f->normal || !f->upperdelaunay || !qh ATinfinity){
- if(!f->center){
- f->center= qh_facetcenter(f->vertices);
- }
- for(int k=0; k<numCoords; k++){
- os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
- }
- }else{
- for(int k=0; k<numCoords; k++){
- os << qh_INFINITE << " "; // FIXUP QH11010 qh_REAL_1
- }
- }
- }else{ // qh CENTERtype==qh_AScentrum
- numCoords= qh hull_dim;
- if(pr.print_format==qh_PRINTtriangles && qh DELAUNAY){
- numCoords--;
- }
- if(!f->center){
- f->center= qh_getcentrum(f);
- }
- for(int k=0; k<numCoords; k++){
- os << f->center[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.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.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(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(qh CENTERtype==qh_ASvoronoi || f->center){
- os << facet.printCenter(pr.run_id, qh_PRINTfacets, " - center: ");
- }
-#if qh_MAXoutside
- if(f->maxoutside > 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(pr.run_id) << "):" << endl;
- for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
- QhullPoint p= *i;
- os << p.print(pr.run_id, " ");
- }
- }else if(ps.size()<21){
- os << ps.print(pr.run_id, " - outside set:");
- }else{
- os << " - outside set: " << ps.size() << " points.";
- os << furthest.print(pr.run_id, " 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(pr.run_id) << "):" << endl;
- for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
- QhullPoint p= *i;
- os << p.print(pr.run_id, " ");
- }
- }else if(cs.size()<21){
- os << cs.print(pr.run_id, " - coplanar set:");
- }else{
- os << " - coplanar set: " << cs.size() << " points.";
- os << furthest.print(pr.run_id, " Furthest");
- }
- zinc_(Zdistio);
- double d= facet.distance(furthest);
- os << " furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
- }
- QhullVertexSet vs= facet.vertices();
- if(!vs.isEmpty()){
- os << vs.print(pr.run_id, " - 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.c]
-//! If qhRunId==UsingLibQhull::NOqhRunId, does not use qh
-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(pr.run_id!=UsingLibQhull::NOqhRunId){
- UsingLibQhull q(pr.run_id);
- // No calls to libqhull
- if(f->visible && 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;
- }
- }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(pr.run_id);
- ++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(pr.run_id);
- 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(pr.run_id);
- }
- }
- }
- return os;
-}//operator<< PrintRidges
-
-// "No conversion" error if defined inline
-ostream &
-operator<<(ostream &os, QhullFacet &f)
-{
- os << f.print(UsingLibQhull::NOqhRunId);
- return os;
-}//<< QhullFacet
diff --git a/src/libqhullpcpp/QhullFacet.h b/src/libqhullpcpp/QhullFacet.h
deleted file mode 100644
index e0d4beb..0000000
--- a/src/libqhullpcpp/QhullFacet.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacet.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLFACET_H
-#define QHULLFACET_H
-
-#include "Coordinates.h"
-#include "QhullHyperplane.h"
-#include "QhullPoint.h"
-#include "QhullSet.h"
-#include "QhullPointSet.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <string>
-#include <vector>
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name ClassRef
- class QhullFacetSet;
- class QhullRidge;
- typedef QhullSet<QhullRidge> QhullRidgeSet;
- class QhullVertex;
- class QhullVertexSet;
-
-#//!\name Types
- //! QhullFacet -- Qhull's facet structure, facetT [libqhull.h], as a C++ class
- class QhullFacet;
-
-//! A QhullFacet is the C++ equivalent to Qhull's facetT*
-class QhullFacet {
-
-private:
-#//!\name Fields -- no additions (QhullFacetSet of facetT*)
- facetT * qh_facet; //! May be 0 (!isDefined) for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
-
-#//!\name Class objects
- static facetT s_empty_facet; // needed for shallow copy
-
-public:
-#//!\name Constants
-
-#//!\name Constructors
- QhullFacet() : qh_facet(&s_empty_facet) {}
- // Creates an alias. Does not copy QhullFacet. Needed for return by value and parameter passing
- QhullFacet(const QhullFacet &o) : qh_facet(o.qh_facet ? o.qh_facet : &s_empty_facet) {}
- // Creates an alias. Does not copy QhullFacet. Needed for vector<QhullFacet>
- QhullFacet & operator=(const QhullFacet &o) { qh_facet= o.qh_facet ? o.qh_facet : &s_empty_facet; return *this; }
- ~QhullFacet() {}
-
-#//!\name Conversion
- //Implicit conversion from facetT
- QhullFacet(facetT *f) : qh_facet(f ? f : &s_empty_facet) {}
- // Do not define facetT(). It conflicts with return type facetT*
- facetT * getFacetT() const { return qh_facet; }
-
-#//!\name QhullSet<QhullFacet>
- facetT * getBaseT() const { return getFacetT(); }
-
-#//!\name getSet
- int dimension() const;
- QhullPoint getCenter(int qhRunId) { return getCenter(qhRunId, qh_PRINTpoints); }
- QhullPoint getCenter(int qhRunId, qh_PRINT printFormat);
- QhullHyperplane hyperplane() const { return QhullHyperplane(dimension(), qh_facet->normal, qh_facet->offset); }
- int id() const { return qh_facet ? qh_facet->id : -1; }
- QhullHyperplane innerplane(int qhRunId) const;
- bool isDefined() const { return qh_facet && qh_facet != &s_empty_facet; }
- bool isGood() const { return qh_facet && qh_facet->good; }
- bool isSimplicial() const { return qh_facet->simplicial; }
- bool isTopOrient() const { return qh_facet->toporient; }
- bool isTriCoplanar() const { return qh_facet->tricoplanar; }
- bool isUpperDelaunay() const { return qh_facet->upperdelaunay; }
- QhullFacet next() const { return qh_facet->next; }
- bool operator==(const QhullFacet &o) const { return qh_facet==o.qh_facet; }
- bool operator!=(const QhullFacet &o) const { return !operator==(o); }
- QhullHyperplane outerplane(int qhRunId) const;
- QhullFacet previous() const { return qh_facet->previous; }
- QhullFacet tricoplanarOwner() const;
- QhullPoint voronoiVertex(int qhRunId);
-
-#//!\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(dimension(), const_cast<coordT *>(p))); }
- double distance(const QhullPoint &p) const { return hyperplane().distance(p); }
- double facetArea(int qhRunId);
-
-#//!\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;
- int run_id;
- qh_PRINT print_format;
- PrintCenter(int qhRunId, QhullFacet &f, qh_PRINT printFormat, const char * s) : facet(&f), message(s), run_id(qhRunId), print_format(printFormat){}
- };//PrintCenter
- PrintCenter printCenter(int qhRunId, qh_PRINT printFormat, const char *message) { return PrintCenter(qhRunId, *this, printFormat, message); }
-
- struct PrintFacet{
- QhullFacet * facet; // non-const due to f->center()
- int run_id;
- PrintFacet(int qhRunId, QhullFacet &f) : facet(&f), run_id(qhRunId) {}
- };//PrintFacet
- PrintFacet print(int qhRunId) { return PrintFacet(qhRunId, *this); }
-
- 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()
- int run_id;
- PrintHeader(int qhRunId, QhullFacet &f) : facet(&f), run_id(qhRunId) {}
- };//PrintHeader
- PrintHeader printHeader(int qhRunId) { return PrintHeader(qhRunId, *this); }
-
- struct PrintRidges{
- const QhullFacet *facet;
- int run_id;
- PrintRidges(int qhRunId, QhullFacet &f) : facet(&f), run_id(qhRunId) {}
- };//PrintRidges
- PrintRidges printRidges(int qhRunId) { return PrintRidges(qhRunId, *this); }
-
-};//class QhullFacet
-
-}//namespace orgQhull
-
-#//!\name Global
-
-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, const orgQhull::QhullFacet::PrintFacet &pr);
-std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
-
-#endif // QHULLFACET_H
diff --git a/src/libqhullpcpp/QhullFacetList.cpp b/src/libqhullpcpp/QhullFacetList.cpp
deleted file mode 100644
index 505a8fc..0000000
--- a/src/libqhullpcpp/QhullFacetList.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacetList.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullFacetList -- Qhull's linked facets, as a C++ class
-
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "QhullPoint.h"
-#include "QhullRidge.h"
-#include "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 {
-
-#//Conversion
-
-// See qt_qhull.cpp for QList conversions
-
-#ifndef QHULL_NO_STL
-std::vector<QhullFacet> QhullFacetList::
-toStdVector() const
-{
- QhullLinkedListIterator<QhullFacet> i(*this);
- std::vector<QhullFacet> 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<QhullVertex> QhullFacetList::
-vertices_toStdVector(int qhRunId) const
-{
- std::vector<QhullVertex> vs;
- QhullVertexSet qvs(qhRunId, first().getFacetT(), NULL, isSelectAll());
-
- for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
- vs.push_back(*i);
- }
- return vs;
-}//vertices_toStdVector
-#endif //QHULL_NO_STL
-
-#//Read-only
-
-bool QhullFacetList::
-contains(const QhullFacet &facet) const
-{
- if(isSelectAll()){
- return QhullLinkedList<QhullFacet>::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<QhullFacet>::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<QhullFacet>::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
-
-#//Global functions
-
-using std::endl;
-using std::ostream;
-using orgQhull::QhullFacet;
-using orgQhull::QhullFacetList;
-using orgQhull::QhullVertex;
-using orgQhull::QhullVertexSet;
-using orgQhull::UsingLibQhull;
-
-ostream &
-operator<<(ostream &os, const QhullFacetList::PrintFacetList &pr)
-{
- QhullFacetList fs= *pr.facet_list;
- os << "Vertices for " << fs.count() << " facets" << endl;
- os << fs.printVertices(pr.run_id);
- os << fs.printFacets(pr.run_id);
- return os;
-}//operator<<
-
-//! Print facet list to stream. From qh_printafacet [io.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(pr.run_id);
- }
- }
- return os;
-}//printFacets
-
-//! Print vertices of good faces in facet list to stream. From qh_printvertexlist [io.c]
-//! Same as vertices_toStdVector
-ostream &
-operator<<(ostream &os, const QhullFacetList::PrintVertices &pr)
-{
- QhullVertexSet vs(pr.run_id, 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(pr.run_id);
- }
- return os;
-}//printVertices
-
-std::ostream &
-operator<<(ostream &os, const QhullFacetList &fs)
-{
- os << fs.printFacets(UsingLibQhull::NOqhRunId);
- return os;
-}//QhullFacetList
-
diff --git a/src/libqhullpcpp/QhullFacetList.h b/src/libqhullpcpp/QhullFacetList.h
deleted file mode 100644
index ef8c537..0000000
--- a/src/libqhullpcpp/QhullFacetList.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacetList.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLFACETLIST_H
-#define QHULLFACETLIST_H
-
-#include "QhullLinkedList.h"
-#include "QhullFacet.h"
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name ClassRef
- class QhullFacet;
-
-#//!\name Types
- //! QhullFacetList -- List of Qhull facets, as a C++ class. See QhullFacetSet.h
- class QhullFacetList;
- //! QhullFacetListIterator -- if(f.isGood()){ ... }
- typedef QhullLinkedListIterator<QhullFacet>
- QhullFacetListIterator;
-
-class QhullFacetList : public QhullLinkedList<QhullFacet> {
-
-#//!\name Fields
-private:
- bool select_all; //! True if include bad facets. Default is false.
-
-#//!\name Constructors
-public:
- QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList<QhullFacet>(b, e), select_all(false) {}
- //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
- QhullFacetList(const QhullFacetList &o) : QhullLinkedList<QhullFacet>(*o.begin(), *o.end()), select_all(o.select_all) {}
- ~QhullFacetList() {}
-
-private:
- //!Disable default constructor and copy assignment. See QhullLinkedList
- QhullFacetList();
- QhullFacetList & operator=(const QhullFacetList &);
-public:
-
-#//!\name Conversion
-#ifndef QHULL_NO_STL
- std::vector<QhullFacet> toStdVector() const;
- std::vector<QhullVertex> vertices_toStdVector(int qhRunId) const;
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- QList<QhullFacet> toQList() const;
- QList<QhullVertex> vertices_toQList(int qhRunId) const;
-#endif //QHULL_USES_QT
-
-#//!\name GetSet
- bool isSelectAll() const { return select_all; }
- void selectAll() { select_all= true; }
- void selectGood() { select_all= false; }
-
-#//!\name Read-only
- //! Filtered by facet.isGood(). May be 0 when !isEmpty().
- int count() const;
- bool contains(const QhullFacet &f) const;
- int count(const QhullFacet &f) const;
- //! operator==() does not depend on isGood()
-
-#//!\name IO
- struct PrintFacetList{
- const QhullFacetList *facet_list;
- int run_id;
- PrintFacetList(int qhRunId, const QhullFacetList &fl) : facet_list(&fl), run_id(qhRunId) {}
- };//PrintFacetList
- PrintFacetList print(int qhRunId) const { return PrintFacetList(qhRunId, *this); }
-
- struct PrintFacets{
- const QhullFacetList *facet_list;
- int run_id;
- PrintFacets(int qhRunId, const QhullFacetList &fl) : facet_list(&fl), run_id(qhRunId) {}
- };//PrintFacets
- PrintFacets printFacets(int qhRunId) const { return PrintFacets(qhRunId, *this); }
-
- struct PrintVertices{
- const QhullFacetList *facet_list;
- int run_id; //! Can not be NOrunId due to qh_facetvertices
- PrintVertices(int qhRunId, const QhullFacetList &fl) : facet_list(&fl), run_id(qhRunId) {}
- };//PrintVertices
- PrintVertices printVertices(int qhRunId) const { return PrintVertices(qhRunId, *this); }
-};//class QhullFacetList
-
-}//namespace orgQhull
-
-#//!\name Global
-
-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/libqhullpcpp/QhullFacetSet.cpp b/src/libqhullpcpp/QhullFacetSet.cpp
deleted file mode 100644
index 21ab56c..0000000
--- a/src/libqhullpcpp/QhullFacetSet.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacetSet.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullFacetSet -- Qhull's linked facets, as a C++ class
-
-#include "QhullFacet.h"
-#include "QhullFacetSet.h"
-#include "QhullPoint.h"
-#include "QhullRidge.h"
-#include "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 {
-
-#//Conversion
-
-// See qt-qhull.cpp for QList conversions
-
-#ifndef QHULL_NO_STL
-std::vector<QhullFacet> QhullFacetSet::
-toStdVector() const
-{
- QhullSetIterator<QhullFacet> i(*this);
- std::vector<QhullFacet> vs;
- while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.push_back(f);
- }
- }
- return vs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#//Read-only
-
-bool QhullFacetSet::
-contains(const QhullFacet &facet) const
-{
- if(isSelectAll()){
- return QhullSet<QhullFacet>::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<QhullFacet>::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<QhullFacet>::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
-
-#//Global functions
-
-using std::endl;
-using std::ostream;
-using orgQhull::QhullFacet;
-using orgQhull::QhullFacetSet;
-using orgQhull::UsingLibQhull;
-
-ostream &
-operator<<(ostream &os, const QhullFacetSet &fs)
-{
- os << fs.print(UsingLibQhull::NOqhRunId, "");
- return os;
-}//<<QhullFacetSet
-
-ostream &
-
-operator<<(ostream &os, const QhullFacetSet::PrintFacetSet &pr)
-{
- QhullFacetSet fs= *pr.facet_set;
- for(QhullFacetSet::iterator i=fs.begin(); i != fs.end(); ++i){
- QhullFacet f= *i;
- if(fs.isSelectAll() || f.isGood()){
- os << f.print(pr.run_id);
- }
- }
- return os;
-}//<< QhullFacetSet::PrintFacetSet
-
-//! Print facet identifiers to stream. Space prefix. From qh_printfacetheader [io.c]
-ostream &
-operator<<(ostream &os, const QhullFacetSet::PrintIdentifiers &p)
-{
- os << p.print_message;
- for(QhullFacetSet::const_iterator i=p.facet_set->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;
-}//<<QhullFacetSet::PrintIdentifiers
-
diff --git a/src/libqhullpcpp/QhullFacetSet.h b/src/libqhullpcpp/QhullFacetSet.h
deleted file mode 100644
index 50e5d47..0000000
--- a/src/libqhullpcpp/QhullFacetSet.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacetSet.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLFACETSET_H
-#define QHULLFACETSET_H
-
-#include "QhullSet.h"
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name ClassRef
- class QhullFacet;
-
-#//!\name Types
- //! QhullFacetSet -- a set of Qhull facets, as a C++ class. See QhullFacetList.h
- class QhullFacetSet;
- typedef QhullSetIterator<QhullFacet>
- QhullFacetSetIterator;
-
-class QhullFacetSet : public QhullSet<QhullFacet> {
-
-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
- explicit QhullFacetSet(setT *s) : QhullSet<QhullFacet>(s), select_all(false) {}
- //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
- QhullFacetSet(const QhullFacetSet &o) : QhullSet<QhullFacet>(o), select_all(o.select_all) {}
-
-private:
- //!Disable default constructor and copy assignment. See QhullSetBase
- QhullFacetSet();
- QhullFacetSet & operator=(const QhullFacetSet &);
-public:
-
-#//!\name Conversion
-#ifndef QHULL_NO_STL
- std::vector<QhullFacet> toStdVector() const;
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- QList<QhullFacet> toQList() const;
-#endif //QHULL_USES_QT
-
-#//!\name GetSet
- bool isSelectAll() const { return select_all; }
- void selectAll() { select_all= true; }
- void selectGood() { select_all= false; }
-
-#//!\name Read-only
- //! Filtered by facet.isGood(). May be 0 when !isEmpty().
- int count() const;
- bool contains(const QhullFacet &f) const;
- int count(const QhullFacet &f) const;
- //! operator==() does not depend on isGood()
-
-#//!\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;
- int run_id;
- PrintFacetSet(int qhRunId, const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message), run_id(qhRunId) {}
- };//PrintFacetSet
- const PrintFacetSet print(int qhRunId, const char *message) const { return PrintFacetSet(qhRunId, message, this); }
-
- struct PrintIdentifiers{
- const QhullFacetSet *facet_set;
- const char * print_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
-
-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/libqhullpcpp/QhullHyperplane.cpp b/src/libqhullpcpp/QhullHyperplane.cpp
deleted file mode 100644
index 48ca96d..0000000
--- a/src/libqhullpcpp/QhullHyperplane.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullHyperplane.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "QhullHyperplane.h"
-#include "QhullPoint.h"
-
-#include <iostream>
-
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//Conversion
-
-// See qt-qhull.cpp for QList conversions
-
-#ifndef QHULL_NO_STL
-std::vector<coordT> QhullHyperplane::
-toStdVector() const
-{
- QhullHyperplaneIterator i(*this);
- std::vector<coordT> fs;
- while(i.hasNext()){
- fs.push_back(i.next());
- }
- fs.push_back(hyperplane_offset);
- return fs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#//Value
-
-//! Return distance from point to hyperplane.
-//! If greater than zero, the point is above the facet (i.e., outside).
-// qh_distplane [geom.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::
-norm() const {
- double d= 0.0;
- const coordT *c= coordinates();
- for (int k=dimension(); k--; ){
- d += *c * *c;
- ++c;
- }
- return sqrt(d);
-}//norm
-
-#//Operator
-
-bool QhullHyperplane::
-operator==(const QhullHyperplane &other) const
-{
- if(hyperplane_dimension!=other.hyperplane_dimension){
- return false;
- }
- double d= fabs(hyperplane_offset-other.hyperplane_offset);
- if(d>UsingLibQhull::globalDistanceEpsilon()){
- return false;
- }
- const coordT *c= hyperplane_coordinates;
- const coordT *c2= other.hyperplane_coordinates;
- if(c==c2){
- return true;
- }
- double dist2= 0.0;
- for(int k= hyperplane_dimension; k--; ){
- double diff= *c++ - *c2++;
- dist2 += diff*diff;
- }
- if(dist2 > UsingLibQhull::globalAngleEpsilon()){
- return false;
- }
- return true;
-}//operator==
-
-#//GetSet
-
-}//namespace orgQhull
-
-#//Global functions
-
-using std::ostream;
-using orgQhull::QhullHyperplane;
-using orgQhull::UsingLibQhull;
-
-#//operator<<
-
-ostream &
-operator<<(ostream &os, const QhullHyperplane &p)
-{
- os << p.print();
- return os;
-}
-
-ostream &
-operator<<(ostream &os, const QhullHyperplane::PrintHyperplane &pr)
-{
- QhullHyperplane p= *pr.hyperplane;
- if(pr.print_message){
- os << pr.print_message;
- }
- 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
- }
- }
- if(pr.hyperplane_offset_message){
- os << pr.hyperplane_offset_message << " " << p.offset();
- }else{
- os << " " << p.offset();
- }
- os << std::endl;
- return os;
-}//PrintHyperplane
-
diff --git a/src/libqhullpcpp/QhullHyperplane.h b/src/libqhullpcpp/QhullHyperplane.h
deleted file mode 100644
index ea966fe..0000000
--- a/src/libqhullpcpp/QhullHyperplane.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullHyperplane.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHHYPERPLANE_H
-#define QHHYPERPLANE_H
-
-#include "QhullError.h"
-#include "QhullIterator.h"
-#include "UsingLibQhull.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-
-namespace orgQhull {
-#//!\name ClassRef
- class QhullPoint;
-
-#//!\name Types
- //! QhullHyperplane as an offset, dimension, and pointer to coordinates
- class QhullHyperplane;
- //! Java-style iterator for QhullHyperplane coordinates
- class QhullHyperplaneIterator;
-
-class QhullHyperplane { // Similar to QhullPoint
-
-private:
-#//!\name Fields
- coordT * hyperplane_coordinates; // Keep pointers aligned
- int hyperplane_dimension;
- coordT hyperplane_offset;
-
-public:
-#//!\name Subtypes
- typedef const coordT * iterator;
- typedef const coordT * const_iterator;
- typedef QhullHyperplane::iterator Iterator;
- typedef QhullHyperplane::const_iterator ConstIterator;
-
-#//!\name Construct
- QhullHyperplane() : hyperplane_coordinates(0), hyperplane_dimension(0), hyperplane_offset(0.0) {};
- QhullHyperplane(int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) : hyperplane_coordinates(c), hyperplane_dimension(hyperplaneDimension), hyperplane_offset(hyperplaneOffset) {}
- // 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), hyperplane_dimension(other.hyperplane_dimension), hyperplane_offset(other.hyperplane_offset) {}
- // Creates an alias. Does not copy the hyperplane's coordinates. Needed for vector<QhullHyperplane>
- QhullHyperplane & operator=(const QhullHyperplane &other) { hyperplane_coordinates= other.hyperplane_coordinates; hyperplane_dimension= other.hyperplane_dimension; hyperplane_offset= other.hyperplane_offset; return *this; }
- ~QhullHyperplane() {}
-
-#//!\name Conversions --
-//! Includes offset at end
-#ifndef QHULL_NO_STL
- std::vector<coordT> toStdVector() const;
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- QList<coordT> toQList() const;
-#endif //QHULL_USES_QT
-
-#//!\name Read-only
-public:
- const coordT * coordinates() const { return hyperplane_coordinates; }
- coordT * coordinates() { return hyperplane_coordinates; }
- int dimension() const { return hyperplane_dimension; }
- bool isDefined() const { return hyperplane_coordinates!=0 && hyperplane_dimension>0; }
- coordT offset() const { return hyperplane_offset; }
-
-#//!\name Define
- 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
- void defineAs(QhullHyperplane &other) { hyperplane_coordinates= other.coordinates(); hyperplane_dimension= other.dimension(); hyperplane_offset= other.offset(); }
- void setCoordinates(coordT *c) { hyperplane_coordinates= c; }
- void setDimension(int hyperplaneDimension) { hyperplane_dimension= hyperplaneDimension; }
- void setOffset(coordT hyperplaneOffset) { hyperplane_offset= hyperplaneOffset; }
-
-#//!\name value
- double distance(const QhullPoint &p) const;
- double norm() const;
-
-#//!\name iterator
- iterator begin() { return hyperplane_coordinates; }
- const_iterator begin() const { return hyperplane_coordinates; }
- const_iterator constBegin() const { return hyperplane_coordinates; }
- const_iterator constEnd() const { return hyperplane_coordinates+hyperplane_dimension; }
- int count() { return dimension(); }
- iterator end() { return hyperplane_coordinates+hyperplane_dimension; }
- const_iterator end() const { return hyperplane_coordinates+hyperplane_dimension; }
- size_t size() { return (size_t)dimension(); }
-
-#//!\name Operator
- 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<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
- coordT & operator[](int idx) { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
-
-#//!\name IO
- struct PrintHyperplane{
- const QhullHyperplane *hyperplane;
- const char * print_message;
- const char * hyperplane_offset_message;
- PrintHyperplane(const char *message, const char *offsetMessage, const QhullHyperplane &p) : hyperplane(&p), print_message(message), hyperplane_offset_message(offsetMessage) {}
- };//PrintHyperplane
- PrintHyperplane print() const { return PrintHyperplane(0, 0, *this); }
- PrintHyperplane print(const char *message, const char *offsetMessage) const { return PrintHyperplane(message, offsetMessage, *this); }
-
-};//QhullHyperplane
-
-QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullHyperplane, coordT)
-
-}//namespace orgQhull
-
-#//!\name Global
-
-std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane::PrintHyperplane &pr);
-std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p); //FIXUP QH11015 -- multiple instances if define here
-
-#endif // QHHYPERPLANE_H
-
diff --git a/src/libqhullpcpp/QhullIterator.h b/src/libqhullpcpp/QhullIterator.h
deleted file mode 100644
index 403b09d..0000000
--- a/src/libqhullpcpp/QhullIterator.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullIterator.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLITERATOR_H
-#define QHULLITERATOR_H
-
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <assert.h>
-#include <string>
-#include <vector>
-//! Avoid dependence on <iterator>
-namespace std { struct bidirectional_iterator_tag; struct random_access_iterator_tag; }
-
-namespace orgQhull {
-
-#//!\name Defined here
- //! 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.h/FOREACHsetelement_()
-
-// Changed c to C* as in Mutable... Assumes c does not go away.
-#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
-#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
-
-#define QHULL_DECLARE_SET_ITERATOR(C) \
-\
- template <class T> \
- class Qhull##C##Iterator \
- { \
- typedef typename Qhull##C<T>::const_iterator const_iterator; \
- Qhull##C<T> c; \
- const_iterator i; \
- public: \
- inline Qhull##C##Iterator(const Qhull##C<T> &container) \
- : c(container), i(c.constBegin()) {} \
- inline Qhull##C##Iterator &operator=(const Qhull##C<T> &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
-
-#define QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) \
-\
-template <class T> \
-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/libqhullpcpp/QhullLinkedList.h b/src/libqhullpcpp/QhullLinkedList.h
deleted file mode 100644
index 0853411..0000000
--- a/src/libqhullpcpp/QhullLinkedList.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullLinkedList.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLLINKEDLIST_H
-#define QHULLLINKEDLIST_H
-
-namespace std { struct bidirectional_iterator_tag; struct random_access_iterator_tag; }
-
-#include "QhullError.h"
-
-#ifdef QHULL_USES_QT
-#include <QtCore/QList>
-#endif
-
-#ifndef QHULL_NO_STL
-#include <algorithm>
-#endif
-
-namespace orgQhull {
-
-#//!\name Type
- //! QhullLinkedList<T> -- 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.
- //! libqhull 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.h/FORALLfacets_()
- //! QhullLinkedList<T>::const_iterator -- STL-style iterator
- //! QhullLinkedList<T>::iterator -- STL-style iterator
- //! QhullLinkedListIterator<T> -- Java-style iterator
- //! Derived from Qt/core/tools/qiterator.h
- //! Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h]
-
-template <typename T>
-class QhullLinkedList
-{
-private:
-#//!\name Fields
- T begin_node;
- T end_node; //! Sentinel node at end of list
-
-public:
-#//!\name Subtypes and types
- class const_iterator;
- class iterator;
- typedef const_iterator ConstIterator;
- typedef iterator Iterator;
- typedef ptrdiff_t difference_type;
- typedef int 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 Constructors
- QhullLinkedList<T>(T b, T e) : begin_node(b), end_node(e) {}
- //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
- QhullLinkedList<T>(const QhullLinkedList<T> &o) : begin_node(o.begin_node), end_node(o.end_node) {}
- ~QhullLinkedList<T>() {}
-
-private:
- //!disabled since a sentinel must be allocated as the private type
- QhullLinkedList<T>() {}
- //!disabled since qs= qs2 is ambiguous (pointer vs. contents)
- QhullLinkedList<T> &operator=(const QhullLinkedList<T> &l) {}
-public:
-
-#//!\name Conversions
-#ifndef QHULL_NO_STL
- std::vector<T> toStdVector() const;
-#endif
-#ifdef QHULL_USES_QT
- QList<T> toQList() const;
-#endif
-
-#//!\name Read-only
- int count() const;
- //count(t) under Search
- bool empty() const { return isEmpty(); }
- bool isEmpty() const { return (begin_node==end_node); }
- bool operator==(const QhullLinkedList<T> &o) const;
- bool operator!=(const QhullLinkedList<T> &o) const { return !operator==(o); }
- size_t size() const { return count(); }
-
-#//!\name Element access
- //! Return by value which contains a pointer (e.g., typedef vertexT * QhullVertex). A reference does not make sense.
- T back() const { return last(); }
- T first() const { QHULL_ASSERT(!isEmpty()); return *begin(); }
- T front() const { return first(); }
- T last() const { QHULL_ASSERT(!isEmpty()); return *--end(); }
-
-#//!\name Modify -- Allocation of opaque types not implemented.
-
-#//!\name Search
- bool contains(const T &t) const;
- int 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(T t) : i(t) {}
- iterator(const iterator &o) : i(o.i) {}
- iterator & operator=(const iterator &o) { i= o.i; return *this; }
-
- T operator*() const { return i; }
- T operator->() const { 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<const iterator &>(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(T t) : i(t) {}
- const_iterator(const const_iterator &o) : i(o.i) {}
- const_iterator(iterator o) : i(o.i) {}
- const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; }
-
- T operator*() const { return i; }
- 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 <typename T>
-class QhullLinkedListIterator // FIXUP QH11016 define QhullMutableLinkedListIterator
-{
- typedef typename QhullLinkedList<T>::const_iterator const_iterator;
- const QhullLinkedList<T> *c;
- const_iterator i;
-
-public:
- QhullLinkedListIterator(const QhullLinkedList<T> &container) : c(&container), i(c->constBegin()) {}
- QhullLinkedListIterator &operator=(const QhullLinkedList<T> &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 Conversion
-
-#ifndef QHULL_NO_STL
-template <typename T>
-std::vector<T> QhullLinkedList<T>::
-toStdVector() const
-{
- std::vector<T> tmp;
- std::copy(constBegin(), constEnd(), std::back_inserter(tmp));
- return tmp;
-}//toStdVector
-#endif
-
-#ifdef QHULL_USES_QT
-template <typename T>
-QList<T> QhullLinkedList<T>::
-toQList() const
-{
- QhullLinkedListIterator<T> i(*this);
- QList<T> ls;
- while(i.hasNext()){
- ls.append(i.next());
- }
- return ls;
-}//toQList
-#endif
-
-#//!\name Read-only
-
-template <typename T>
-int QhullLinkedList<T>::
-count() const
-{
- const_iterator i= begin_node;
- int c= 0;
- while(i != end_node){
- c++;
- i++;
- }
- return c;
-}//count
-
-#//!\name Search
-
-template <typename T>
-bool QhullLinkedList<T>::
-contains(const T &t) const
-{
- const_iterator i= begin_node;
- while(i != end_node){
- if(i==t){
- return true;
- }
- i++;
- }
- return false;
-}//contains
-
-template <typename T>
-int QhullLinkedList<T>::
-count(const T &t) const
-{
- const_iterator i= begin_node;
- int c= 0;
- while(i != end_node){
- if(i==t){
- c++;
- }
- i++;
- }
- return c;
-}//count
-
-template <typename T>
-bool QhullLinkedList<T>::
-operator==(const QhullLinkedList<T> &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<T>(i.next());
- il= static_cast<T>(il.next());
- }
- if(il != l.end_node){
- return false;
- }
- return true;
-}//operator==
-
-#//!\name Iterator
-
-template <typename T>
-typename QhullLinkedList<T>::iterator QhullLinkedList<T>::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 T>
-typename QhullLinkedList<T>::const_iterator QhullLinkedList<T>::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 <typename T>
-bool QhullLinkedListIterator<T>::
-findNext(const T &t)
-{
- while(i != c->constEnd()){
- if (*i++ == t){
- return true;
- }
- }
- return false;
-}//findNext
-
-template <typename T>
-bool QhullLinkedListIterator<T>::
-findPrevious(const T &t)
-{
- while(i!=c->constBegin()){
- if(*(--i)==t){
- return true;
- }
- }
- return false;
-}//findNext
-
-}//namespace orgQhull
-
-#//!\name Global
-
-template <typename T>
-std::ostream &
-operator<<(std::ostream &os, const orgQhull::QhullLinkedList<T> &qs)
-{
- typename orgQhull::QhullLinkedList<T>::const_iterator i;
- for(i= qs.begin(); i != qs.end(); ++i){
- os << *i;
- }
- return os;
-}//operator<<
-
-#endif // QHULLLINKEDLIST_H
-
diff --git a/src/libqhullpcpp/QhullPoint.cpp b/src/libqhullpcpp/QhullPoint.cpp
deleted file mode 100644
index b562d20..0000000
--- a/src/libqhullpcpp/QhullPoint.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullPoint.cpp#4 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "UsingLibQhull.h"
-#include "QhullPoint.h"
-
-#include <iostream>
-#include <algorithm>
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//Class public variables and methods
-
-//! If qhRundID undefined uses QhullPoint::s_points_begin and dimension
-int QhullPoint::
-id(int qhRunId, int dimension, const coordT *c)
-{
- QHULL_UNUSED(dimension);
-
- if(UsingLibQhull::hasPoints()){
- if(qhRunId==UsingLibQhull::NOqhRunId){
- const coordT *pointsEnd;
- int dim;
- const coordT *points= UsingLibQhull::globalPoints(&dim, &pointsEnd);
- if(c>=points && c<pointsEnd){
- int offset= (int)(c-points); // WARN64
- return offset/dim;
- }
- }else{
- UsingLibQhull q(qhRunId);
- // NOerrors from qh_pointid or qh_setindex
- return qh_pointid(const_cast<coordT *>(c));
- }
- }
- long long i=(long long)c;
- return (int)i; // WARN64
-}//id
-
-#//Conversion
-
-// See qt-qhull.cpp for QList conversion
-
-#ifndef QHULL_NO_STL
-std::vector<coordT> QhullPoint::
-toStdVector() const
-{
- QhullPointIterator i(*this);
- std::vector<coordT> vs;
- while(i.hasNext()){
- vs.push_back(i.next());
- }
- return vs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#//Operator
-
-//! QhullPoint is equal if it has the same address and dimension, or if the coordinates are within sqrt(qh_qh->distanceEpsilon())
-//! Uses sqrt() since globalDistanceEpsilon is the roundoff for distance to hyperplane, i.e., the inner product
-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;
- }
- double dist2= 0.0;
- for(int k= point_dimension; k--; ){
- double diff= *c++ - *c2++;
- dist2 += diff*diff;
- }
- return (dist2 <= UsingLibQhull::globalDistanceEpsilon());
- }//operator==
-
-
-#//Value
-
-//! Return distance between two points.
-double QhullPoint::
-distance(const QhullPoint &p) const
-{
- const coordT *c= coordinates();
- const coordT *c2= p.coordinates();
- int dim= dimension();
- QHULL_ASSERT(dim==p.dimension());
- 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
-
-#//Global functions
-
-using std::ostream;
-using orgQhull::QhullPoint;
-using orgQhull::UsingLibQhull;
-
-#//operator<<
-
-ostream &
-operator<<(ostream &os, const QhullPoint &p)
-{
- os << p.printWithIdentifier(UsingLibQhull::NOqhRunId, "");
- return os;
-}
-
-//! Same as qh_printpointid [io.c]
-ostream &
-operator<<(ostream &os, const QhullPoint::PrintPoint &pr)
-{
- QhullPoint p= *pr.point;
- int i= p.id(pr.run_id);
- if(pr.point_message){
- if(*pr.point_message){
- os << pr.point_message << " ";
- }
- if(pr.with_identifier && (i!=-1)){
- 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
-
diff --git a/src/libqhullpcpp/QhullPoint.h b/src/libqhullpcpp/QhullPoint.h
deleted file mode 100644
index 3a3432c..0000000
--- a/src/libqhullpcpp/QhullPoint.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullPoint.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHPOINT_H
-#define QHPOINT_H
-
-#include "QhullError.h"
-#include "QhullIterator.h"
-#include "UsingLibQhull.h"
-#include "Coordinates.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name Types
- //! QhullPoint as a pointer and dimension to shared memory
- class QhullPoint;
- //! Java-style iterator for QhullPoint coordinates
- class QhullPointIterator;
-
-class QhullPoint {
-
- //! A point is a pointer into an array of coordinates.
-
-private:
-#//!\name Fields
- coordT * point_coordinates; // Keep pointers aligned
- int point_dimension;
-
-public:
-#//!\name Subtypes
- typedef const coordT * iterator;
- typedef const coordT * const_iterator;
- typedef QhullPoint::iterator Iterator;
- typedef QhullPoint::const_iterator ConstIterator;
-
-#//!\name Class methods -- Convert point to id w/o QhullQh data structure
- static int id(const coordT *c) { return QhullPoint::id(UsingLibQhull::NOqhRunId, 0, c); }
- static int id(int qhRunId, const coordT *c) { return QhullPoint::id(qhRunId, 0, c); }
- static int id(int qhRunId, int dimension, const coordT *c);
-
-#//!\name Construct
- QhullPoint() : point_coordinates(0), point_dimension(0) {};
- QhullPoint(int pointDimension, coordT *c) : point_coordinates(c), point_dimension(pointDimension) {}
- explicit QhullPoint(Coordinates &c) : point_coordinates(c.data()), point_dimension(c.count()) {}
- // Creates an alias. Does not copy the point. Needed for return by value and parameter passing.
- QhullPoint(const QhullPoint &other) : point_coordinates(other.point_coordinates), point_dimension(other.point_dimension) {}
- // Creates an alias. Does not copy the point. Needed for vector<QhullPoint>
- QhullPoint & operator=(const QhullPoint &other) { point_coordinates= other.point_coordinates; point_dimension= other.point_dimension; return *this; }
- ~QhullPoint() {}
-
-#//!\name Conversions
- // see coordinates()
-#ifndef QHULL_NO_STL
- std::vector<coordT> toStdVector() const;
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- QList<coordT> toQList() const;
-#endif //QHULL_USES_QT
-
-#//!\name Read-only
-public:
- const coordT * coordinates() const { return point_coordinates; }
- coordT * coordinates() { return point_coordinates; }
- int dimension() const { return point_dimension; }
- int id(int qhRunId) const { return id(qhRunId, dimension(), coordinates()); }
- int id() const { return id(UsingLibQhull::NOqhRunId, dimension(), coordinates()); }
- bool isDefined() const { return point_coordinates!=0 && point_dimension>0; }
-
-#//!\name Define
- void advancePoint(int idx) { point_coordinates += idx*point_dimension; }
- void defineAs(int pointDimension, coordT *c) { QHULL_ASSERT(pointDimension>=0); point_coordinates= c; point_dimension= pointDimension; }
- //! Creates an alias to other
- void defineAs(QhullPoint &other) { point_coordinates= other.coordinates(); point_dimension= other.dimension(); }
- void setCoordinates(coordT *c) { point_coordinates= c; }
- void setDimension(int pointDimension) { point_dimension= pointDimension; }
-
-#//!\name value
- double distance(const QhullPoint &p) const;
-
-#//!\name iterator
- iterator begin() { return point_coordinates; }
- const_iterator begin() const { return point_coordinates; }
- const_iterator constBegin() const { return point_coordinates; }
- const_iterator constEnd() const { return point_coordinates+point_dimension; }
- int count() { return dimension(); }
- iterator end() { return point_coordinates+point_dimension; }
- const_iterator end() const { return point_coordinates+point_dimension; }
- size_t size() { return (size_t)dimension(); }
-
-#//!\name Operator
- bool operator==(const QhullPoint &other) const;
- bool operator!=(const QhullPoint &other) const { return !operator==(other); }
- const coordT & operator[](int idx) const { QHULL_ASSERT(idx>=0 && idx<point_dimension); return *(point_coordinates+idx); }
- coordT & operator[](int idx) { QHULL_ASSERT(idx>=0 && idx<point_dimension); return *(point_coordinates+idx); }
-
- struct PrintPoint{
- const QhullPoint *point;
- const char * point_message;
- int run_id;
- bool with_identifier;
- PrintPoint(int qhRunId, const char *message, bool withIdentifier, const QhullPoint &p) : point(&p), point_message(message), run_id(qhRunId), with_identifier(withIdentifier) {}
- };//PrintPoint
- PrintPoint print() const { return PrintPoint(UsingLibQhull::NOqhRunId, "", false, *this); }
- PrintPoint print(int qhRunId) const { return PrintPoint(qhRunId, "", true, *this); }
- PrintPoint print(int qhRunId, const char *message) const { return PrintPoint(qhRunId, message, false, *this); }
- PrintPoint printWithIdentifier(int qhRunId, const char *message) const { return PrintPoint(qhRunId, message, true, *this); }
-
-};//QhullPoint
-
-QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullPoint, coordT)
-
-}//namespace orgQhull
-
-#//!\name Global
-
-std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint::PrintPoint &pr);
-std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint &p); // FIXUP QH11017 OK in c program but not inline { os << p.print(orgQhull::UsingLibQhull::NOqhRunId, ""); return os; }
-
-#endif // QHPOINT_H
-
diff --git a/src/libqhullpcpp/QhullPointSet.cpp b/src/libqhullpcpp/QhullPointSet.cpp
deleted file mode 100644
index bf53f24..0000000
--- a/src/libqhullpcpp/QhullPointSet.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullPointSet.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "QhullPointSet.h"
-
-#include <iostream>
-#include <algorithm>
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#// Conversion
-
-// See qt-qhull.cpp for QList conversion
-
-#ifndef QHULL_NO_STL
-std::vector<QhullPoint> QhullPointSet::
-toStdVector() const
-{
- QhullPointSetIterator i(*this);
- std::vector<QhullPoint> vs;
- while(i.hasNext()){
- vs.push_back(i.next());
- }
- return vs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#//Element-access
-//! Derived from QhullSet::value
-QhullPoint QhullPointSet::
-value(int idx) const
-{
- // Avoid call to qh_setsize() and assert in elementPointer()
- //const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
- void **n= reinterpret_cast<void **>(&SETelem_(getSetT(), idx));
- coordT **n2= reinterpret_cast<coordT **>(n);
- if(idx>=0 && n<endPointer()){
- return QhullPoint(dimension(), *n2);
- }else{
- return QhullPoint();
- }
-}//value
-
-//! Non-const since copy is an alias
-//! Derived from QhullSet::value
-QhullPoint QhullPointSet::
-value(int idx, QhullPoint &defaultValue) const
-{
- // Avoid call to qh_setsize() and assert in elementPointer()
- void **n= reinterpret_cast<void **>(&SETelem_(getSetT(), idx));
- coordT **n2= reinterpret_cast<coordT **>(n);
- if(idx>=0 && n<endPointer()){
- return QhullPoint(dimension(), *n2);
- }else{
- return defaultValue;
- }
-}//value
-
-#//Read-only
-
-bool QhullPointSet::
-operator==(const QhullPointSet &o) const
-{
- if(dimension()!=o.dimension() || count()!=o.count()){
- return false;
- }
- QhullPointSetIterator i(*this);
- QhullPointSetIterator j(o);
- while(i.hasNext()){
- if(i.next()!=j.next()){
- return false;
- }
- }
- return true;
-}//operator==
-
-#//Search
-bool QhullPointSet::
-contains(const QhullPoint &t) const
-{
- QhullPointSetIterator i(*this);
- while(i.hasNext()){
- if(i.next()==t){
- return true;
- }
- }
- return false;
-}//contains
-
-int QhullPointSet::
-count(const QhullPoint &t) const
-{
- int n= 0;
- QhullPointSetIterator i(*this);
- while(i.hasNext()){
- if(i.next()==t){
- ++n;
- }
- }
- return n;
-}//count
-
-int QhullPointSet::
-indexOf(const QhullPoint &t) const
-{
- int idx= 0;
- QhullPointSetIterator i(*this);
- while(i.hasNext()){
- if(i.next()==t){
- return idx;
- }
- ++idx;
- }
- return -1;
-}//indexOf
-
-int QhullPointSet::
-lastIndexOf(const QhullPoint &t) const
-{
- int idx= count()-1;
- QhullPointSetIterator i(*this);
- i.toBack();
- while(i.hasPrevious()){
- if(i.previous()==t){
- break;
- }
- --idx;
- }
- return idx;
-}//lastIndexOf
-
-
-#//QhullPointSetIterator
-
-bool QhullPointSetIterator::
-findNext(const QhullPoint &p)
-{
- while(i!=c->constEnd()){
- if(*i++ == p){
- return true;
- }
- }
- return false;
-}//findNext
-
-bool QhullPointSetIterator::
-findPrevious(const QhullPoint &p)
-{
- while(i!=c->constBegin()){
- if(*(--i) == p){
- return true;
- }
- }
- return false;
-}//findPrevious
-
-}//namespace orgQhull
-
-#//Global functions
-
-using std::endl;
-using std::ostream;
-using orgQhull::QhullPoint;
-using orgQhull::QhullPointSet;
-using orgQhull::UsingLibQhull;
-
-#//operator<<
-
-ostream &
-operator<<(ostream &os, const QhullPointSet &ps)
-{
- os << ps.print(UsingLibQhull::NOqhRunId);
- return os;
-}//<<QhullPointSet
-
-ostream &
-operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr)
-{
- const QhullPointSet s= *pr.point_set;
- if (pr.print_message) {
- os << pr.print_message;
- }
- for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
- if(i!=s.begin()){
- os << " ";
- }
- const QhullPoint point= *i;
- int id= point.id(pr.run_id);
- os << "p" << id;
- }
- os << endl;
- return os;
-}//PrintIdentifiers
-
-ostream &
-operator<<(ostream &os, const QhullPointSet::PrintPointSet &pr)
-{
- const QhullPointSet s= *pr.point_set;
- if (pr.print_message) {
- os << pr.print_message;
- }
- for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
- const QhullPoint point= *i;
- os << point.print(pr.run_id);
- }
- return os;
-}//printPointSet
-
-
diff --git a/src/libqhullpcpp/QhullPointSet.h b/src/libqhullpcpp/QhullPointSet.h
deleted file mode 100644
index 0a4a3a1..0000000
--- a/src/libqhullpcpp/QhullPointSet.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullPointSet.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLPOINTSET_H
-#define QHULLPOINTSET_H
-
-#include "QhullSet.h"
-#include "QhullPoint.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name Types
- //! QhullPointSet -- a set of coordinate pointers with dimension
- // with const_iterator and iterator
- class QhullPointSet;
- //! Java-style iterator
- class QhullPointsIterator;
-
-#//!\name Classref
- class QhullPoint;
-
-class QhullPointSet : public QhullSet<coordT *> {
-
-private:
-#//!\name Fields
- int point_dimension;
-
-public:
-#//!\name Subtypes and types
- class const_iterator;
- class iterator;
- typedef QhullPointSet::const_iterator ConstIterator;
- typedef QhullPointSet::iterator Iterator;
-
- typedef QhullPoint value_type;
- typedef ptrdiff_t difference_type;
- typedef int size_type;
- //typedef const value_type *const_pointer; // FIXUP QH11019: QhullPointSet does not define pointer or reference due to point_dimension
- //typedef const value_type &const_reference;
- //typedef value_type *pointer;
- //typedef value_type &reference;
-
-#//!\name Construct
- //Conversion from setT* is not type-safe. Implicit conversion for void* to T
- QhullPointSet(int pointDimension, setT *s) : QhullSet<coordT *>(s), point_dimension(pointDimension) {}
- //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
- QhullPointSet(const QhullPointSet &o) : QhullSet<coordT *>(o), point_dimension(o.point_dimension) {}
- ~QhullPointSet() {}
-
-//Default constructor and copy assignment disabled since p= p2 is ambiguous (coord* vs coord)
-private:
- QhullPointSet();
- QhullPointSet & operator=(const QhullPointSet &);
-public:
-
-#//!\name Conversions
- // inherited -- constData, data
-#ifndef QHULL_NO_STL
- std::vector<QhullPoint> toStdVector() const;
-#endif
-#ifdef QHULL_USES_QT
- QList<QhullPoint> toQList() const;
-#endif
-
-#//!\name Read-only
- //inherits count, empty, isEmpty, size
- using QhullSetBase::count;
- int dimension() const { return point_dimension; }
- bool operator==(const QhullPointSet &o) const;
- bool operator!=(const QhullPointSet &o) const { return !operator==(o); }
-
-#//!\name Element access
- //! Can not return references since QhullPoint must be generated
- QhullPoint at(int idx) const { return operator[](idx); }
- QhullPoint back() const { return last(); }
- //! end element is NULL
- QhullPoint first() const { QHULL_ASSERT(!isEmpty()); return *begin(); }
- QhullPoint front() const { return first(); }
- QhullPoint last() const { QHULL_ASSERT(!isEmpty()); return *(end()-1); }
- // mid() not available. No setT constructor
- QhullPoint operator[](int idx) const { return QhullPoint(dimension(), QhullSet<coordT *>::operator[](idx)); }
- QhullPoint second() const { return operator[](1); }
- QhullPoint value(int idx) const;
- // Non-const since copy is an alias
- QhullPoint value(int idx, QhullPoint &defaultValue) const;
-
-#//!\name iterator
- iterator begin() { return iterator(dimension(), reinterpret_cast<coordT **>(beginPointer())); }
- const_iterator begin() const { return const_iterator(dimension(), reinterpret_cast<coordT **>(beginPointer())); }
- const_iterator constBegin() const { return const_iterator(dimension(), reinterpret_cast<coordT **>(beginPointer())); }
- const_iterator constEnd() const { return const_iterator(dimension(), reinterpret_cast<coordT **>(endPointer())); }
- iterator end() { return iterator(dimension(), reinterpret_cast<coordT **>(endPointer())); }
- const_iterator end() const { return const_iterator(dimension(), reinterpret_cast<coordT **>(endPointer())); }
-
-//Read-write -- Not available, no setT constructor
-
-#//!\name Search
- bool contains(const QhullPoint &t) const;
- int count(const QhullPoint &t) const;
- int indexOf(const QhullPoint &t) const;
- int lastIndexOf(const QhullPoint &t) const;
-
- // before const_iterator for conversion with comparison operators
- class iterator {
- friend class const_iterator;
-
- private:
- coordT ** i;
- int point_dimension;
-
- public:
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef QhullPoint *pointer;
- typedef QhullPoint &reference;
- typedef QhullPoint value_type;
-
- iterator() : i(0), point_dimension(0) {}
- iterator(int dimension, coordT **c) : i(c), point_dimension(dimension) {}
- iterator(const iterator &o) : i(o.i), point_dimension(o.point_dimension) {}
- iterator & operator=(const iterator &o) { i= o.i; point_dimension= o.point_dimension; return *this; }
-
- QhullPoint operator*() const { return QhullPoint(point_dimension, *i); }
- //operator->() n/a, value-type
- QhullPoint operator[](int idx) { return QhullPoint(point_dimension, *(i+idx)); }
- bool operator==(const iterator &o) const { return i == o.i && point_dimension == o.point_dimension; }
- bool operator!=(const iterator &o) const { return !operator==(o); }
- bool operator==(const const_iterator &o) const
- { return i == reinterpret_cast<const iterator &>(o).i && point_dimension == reinterpret_cast<const iterator &>(o).point_dimension; }
- bool operator!=(const const_iterator &o) const { return !operator==(o); }
-
- //! Assumes same point set
- int operator-(const iterator &o) { return (int)(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<o.i; }
- bool operator>=(const iterator &o) const { return !operator<(o); }
- bool operator>(const const_iterator &o) const
- { return i > reinterpret_cast<const iterator &>(o).i; }
- bool operator<=(const const_iterator &o) const { return !operator>(o); }
- bool operator<(const const_iterator &o) const
- { return i < reinterpret_cast<const iterator &>(o).i; }
- bool operator>=(const const_iterator &o) const { return !operator<(o); }
-
- 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+(int j) const { return iterator(point_dimension, i+j); }
- iterator operator-(int j) const { return operator+(-j); }
- iterator & operator+=(int j) { i += j; return *this; }
- iterator & operator-=(int j) { i -= j; return *this; }
- };//QhullPointSet::iterator
-
- class const_iterator {
- private:
- coordT ** i;
- int point_dimension;
-
- public:
- typedef std::random_access_iterator_tag iterator_category;
- typedef QhullPoint value_type;
- typedef value_type *pointer;
- typedef value_type &reference;
- typedef ptrdiff_t difference_type;
-
- const_iterator() : i(0), point_dimension(0) {}
- const_iterator(int dimension, coordT **c) : i(c), point_dimension(dimension) {}
- const_iterator(const const_iterator &o) : i(o.i), point_dimension(o.point_dimension) {}
- const_iterator(iterator o) : i(o.i), point_dimension(o.point_dimension) {}
- const_iterator &operator=(const const_iterator &o) { i= o.i; point_dimension= o.point_dimension; return *this; }
-
- QhullPoint operator*() const { return QhullPoint(point_dimension, *i); }
- QhullPoint operator[](int idx) { return QhullPoint(point_dimension, *(i+idx)); }
- //operator->() n/a, value-type
- bool operator==(const const_iterator &o) const { return i == o.i && point_dimension == o.point_dimension; }
- bool operator!=(const const_iterator &o) const { return !operator==(o); }
-
- //! Assumes same point set
- int operator-(const const_iterator &o) { return (int)(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<o.i; }
- bool operator>=(const const_iterator &o) const { return !operator<(o); }
-
- 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(point_dimension, 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
-
-#//!\name IO
- struct PrintIdentifiers{
- const QhullPointSet *point_set;
- const char * print_message;
- int run_id;
- 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;
- int run_id;
- PrintPointSet(int qhRunId, const char *message, const QhullPointSet &s) : point_set(&s), print_message(message), run_id(qhRunId) {}
- };//PrintPointSet
- PrintPointSet print(int qhRunId) const { return PrintPointSet(qhRunId, 0, *this); }
- PrintPointSet print(int qhRunId, const char *message) const { return PrintPointSet(qhRunId, message, *this); }
-
-};//QhullPointSet
-
-//derived from qiterator.h
-class QhullPointSetIterator { // FIXUP QH11020 define QhullMutablePointSetIterator
- typedef QhullPointSet::const_iterator const_iterator;
- const QhullPointSet *c;
- const_iterator i;
-
-public:
- QhullPointSetIterator(const QhullPointSet &container) : c(&container), i(c->constBegin()) {}
- QhullPointSetIterator &operator=(const QhullPointSet &container) { c= &container; i= c->constBegin(); return *this; }
- bool findNext(const QhullPoint &p);
- bool findPrevious(const QhullPoint &p);
- bool hasNext() const { return i != c->constEnd(); }
- bool hasPrevious() const { return i != c->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= c->constEnd(); }
- void toFront() { i= c->constBegin(); }
-};//QhullPointSetIterator
-
-}//namespace orgQhull
-
-#//!\name Global
-
-std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet &fs); // Not inline to avoid using statement
-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/libqhullpcpp/QhullPoints.cpp b/src/libqhullpcpp/QhullPoints.cpp
deleted file mode 100644
index 56b15aa..0000000
--- a/src/libqhullpcpp/QhullPoints.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullPoints.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "QhullPoints.h"
-
-#include <iostream>
-#include <algorithm>
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//Conversion
-// See qt-qhull.cpp for QList conversion
-
-#ifndef QHULL_NO_STL
-std::vector<QhullPoint> QhullPoints::
-toStdVector() const
-{
- QhullPointsIterator i(*this);
- std::vector<QhullPoint> vs;
- while(i.hasNext()){
- vs.push_back(i.next());
- }
- return vs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#//Read-only
-
-int QhullPoints::
-extraCoordinatesCount() const
-{
- if(point_dimension>0){
- return (int)((point_end-point_first)%(size_t)point_dimension);
- }
- return 0;
-}//extraCoordinatesCount
-
-bool QhullPoints::
-operator==(const QhullPoints &other) const
-{
- if(point_dimension!=other.point_dimension || (point_end-point_first) != (other.point_end-other.point_first)){
- return false;
- }
- const coordT *c= point_first;
- const coordT *c2= other.point_first;
- while(c<point_end){
- if(*c++!=*c2++){
- return false;
- }
- }
- return true;
-}//operator==
-
-
-#//ElementAccess
-QhullPoints QhullPoints::
-mid(int idx, int length) const
-{
- int n= count();
- if(idx<0 || idx>=n){
- n= 0;
- }else if(length<0 || idx+length>=n){
- n -= idx;
- }else{
- n -= idx+length;
- }
- return QhullPoints(point_dimension, n*point_dimension, point_first+idx*point_dimension);
-}//mid
-
-QhullPoint QhullPoints::
-value(int idx) const
-{
- QhullPoint p;
- if(idx>=0 && idx<count()){
- p.defineAs(point_dimension, point_first+idx*point_dimension);
- }
- return p;
-}//value
-
-QhullPoint QhullPoints::
-value(int idx, QhullPoint &defaultValue) const
-{
- QhullPoint p;
- if(idx>=0 && idx<count()){
- p.defineAs(point_dimension, point_first+idx*point_dimension);
- }else{
- p.defineAs(defaultValue);
- }
- return p;
-}//value
-
-#//Search
-
-bool QhullPoints::
-contains(const QhullPoint &t) const
-{
- const_iterator i= begin();
- while(i != end()){
- if(*i==t){
- return true;
- }
- i++;
- }
- return false;
-}//contains
-
-int QhullPoints::
-count(const QhullPoint &t) const
-{
- int n= 0;
- const_iterator i= begin();
- while(i != end()){
- if(*i==t){
- ++n;
- }
- i++;
- }
- return n;
-}//count
-
-int QhullPoints::
-indexOf(const coordT *pointCoordinates) const
-{
- if(!includesCoordinates(pointCoordinates) || dimension()==0){
- return -1;
- }
- size_t offset= pointCoordinates-point_first;
- int idx= (int)(offset/(size_t)dimension()); // int for error reporting
- int extra= (int)(offset%(size_t)dimension());
- if(extra!=0){
- throw QhullError(10066, "Qhull error: coordinates %x are not at point boundary (extra %d at index %d)", extra, idx, 0.0, pointCoordinates);
- }
- return idx;
-}//indexOf coordT
-
-int QhullPoints::
-indexOf(const coordT *pointCoordinates, int noThrow) const
-{
- size_t extra= 0;
- if(noThrow){
- if(!includesCoordinates(pointCoordinates) || dimension()==0){
- return -1;
- }
- extra= (pointCoordinates-point_first)%(size_t)dimension();
- }
- return indexOf(pointCoordinates-extra);
-}//indexOf coordT noThrow
-
-int QhullPoints::
-indexOf(const QhullPoint &t) const
-{
- int j=0;
- const_iterator i= begin();
- while(i!=end()){
- if(*i==t){
- return j;
- }
- ++i;
- ++j;
- }
- return -1;
-}//indexOf
-
-int QhullPoints::
-lastIndexOf(const QhullPoint &t) const
-{
- int j=count();
- const_iterator i= end();
- while(i != begin()){
- --i;
- --j;
- if(*i==t){
- return j;
- }
- }
- return -1;
-}//lastIndexOf
-
-#//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
-
-#//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<<QhullPoints
-
-ostream &
-operator<<(ostream &os, const QhullPoints::PrintPoints &pr)
-{
- os << pr.point_message;
- QhullPoints ps= *pr.points;
- for(QhullPoints::iterator i=ps.begin(); i != ps.end(); ++i){
- QhullPoint p= *i;
- if(pr.with_identifier){
- os << p.printWithIdentifier(pr.run_id, "");
- }else{
- os << p.print(pr.run_id, "");
- }
- }
- return os;
-}//<<PrintPoints
diff --git a/src/libqhullpcpp/QhullPoints.h b/src/libqhullpcpp/QhullPoints.h
deleted file mode 100644
index 762369b..0000000
--- a/src/libqhullpcpp/QhullPoints.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullPoints.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLPOINTS_H
-#define QHULLPOINTS_H
-
-#include "QhullPoint.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name Types
- //! coordinate pointer with dimension
- // with const_iterator and iterator
- class QhullPoints;
- //! Java-style iterator
- class QhullPointsIterator;
-
-class QhullPoints {
-
- // QhullPoints consists of pointers into an array of coordinates.
-
-private:
-#//!\name Fields
- coordT * point_first;
- coordT * point_end; // end>=first. Trailing coordinates ignored
- int point_dimension; // >= 0
-
-public:
-#//!\name Subtypes
- class const_iterator;
- class iterator;
- typedef QhullPoints::const_iterator ConstIterator;
- typedef QhullPoints::iterator Iterator;
-
-#//!\name Construct
- QhullPoints() : point_first(0), point_end(0), point_dimension(0) {};
- QhullPoints(int pointDimension) : point_first(0), point_end(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
- QhullPoints(int pointDimension, int coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0 && coordinateCount2>=0 ); }
- //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), point_dimension(other.point_dimension) {}
- ~QhullPoints() {}
-
-//disabled since p= p2 is ambiguous (coord* vs coord)
-private:
- QhullPoints & operator=(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; point_dimension= other.point_dimension; return *this; }
-public:
-
-#//!\name Conversion
- const coordT * constData() const { return coordinates(); }
- // See coordinates()
- coordT * data() { return coordinates(); }
- const coordT * data() const { return coordinates(); }
-#ifndef QHULL_NO_STL
- std::vector<QhullPoint> toStdVector() const;
-#endif //QHULL_NO_STL
-#ifdef QHULL_USES_QT
- QList<QhullPoint> toQList() const;
-#endif //QHULL_USES_QT
-
-#//!\name GetSet
- coordT * coordinates() const { return point_first; }
- int coordinateCount() const { return (int)(point_end-point_first); } // WARN64
- int count() const { return (int)size(); } // WARN64
- void defineAs(int pointDimension, int coordinatesCount, coordT *c) { QHULL_ASSERT(pointDimension>=0 && coordinatesCount>=0 && c!=0); point_first= c; point_end= c+coordinatesCount; point_dimension= pointDimension; }
- void defineAs(int coordinatesCount, coordT *c) { QHULL_ASSERT((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; point_dimension= other.point_dimension; }
- int dimension() const { return point_dimension; }
- bool empty() const { return point_end==point_first; }
- coordT * extraCoordinates() const { return extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0; }
- int extraCoordinatesCount() const { return point_dimension>0 ? (int)((point_end-point_first)%(size_t)point_dimension) : 0; } // WARN64
- bool includesCoordinates(const coordT *c) const { return c>=point_first && c<point_end; }
- bool isEmpty() const { return empty(); }
- bool operator==(const QhullPoints &other) const;
- bool operator!=(const QhullPoints &other) const { return !operator==(other); }
- void setDimension(int pointDimension) { QHULL_ASSERT(pointDimension>=0); point_dimension= pointDimension; }
- size_t size() const { return (point_dimension ? (point_end-point_first)/point_dimension : 0); }
-
-#//!\name Element access
- //! Can not return references since QhullPoint must be generated
- QhullPoint at(int idx) const { coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p<point_end); return QhullPoint(point_dimension, p); }
- QhullPoint back() const { return last(); }
- QhullPoint first() const { return QhullPoint(point_dimension, point_first); }
- QhullPoint front() const { return first(); }
- QhullPoint last() const { return QhullPoint(point_dimension, point_end - point_dimension); }
- //! Returns a subset of the points, not a copy
- QhullPoints mid(int idx, int length= -1) const;
- QhullPoint operator[](int idx) const { return at(idx); }
- QhullPoint value(int idx) const;
- // Non-const since copy is an alias
- QhullPoint value(int idx, QhullPoint &defaultValue) const;
-
-#//!\name Foreach
- ConstIterator begin() const { return ConstIterator(*this); }
- Iterator begin() { return Iterator(*this); }
- ConstIterator constBegin() const { return ConstIterator(*this); }
- ConstIterator constEnd() const { return ConstIterator(point_dimension, point_end); }
- ConstIterator end() const { return ConstIterator(point_dimension, point_end); }
- Iterator end() { return Iterator(point_dimension, point_end); }
-
-#//!\name Search
- bool contains(const QhullPoint &t) const;
- int count(const QhullPoint &t) const;
- int indexOf(const coordT *pointCoordinates) const;
- int indexOf(const coordT *pointCoordinates, int noThrow) const;
- int indexOf(const QhullPoint &t) const;
- int lastIndexOf(const QhullPoint &t) const;
-
-#//!\name QhullPoints::iterator -- modeled on qvector.h and qlist.h
- // before const_iterator for conversion with comparison operators
- // See: QhullSet.h
- class iterator : public QhullPoint {
-
- public:
- typedef std::random_access_iterator_tag iterator_category;
- typedef QhullPoint value_type;
- typedef value_type *pointer;
- typedef value_type &reference;
- typedef ptrdiff_t difference_type;
-
- iterator() : QhullPoint() {}
- iterator(const iterator &other): QhullPoint(*other) {}
- explicit iterator(const QhullPoints &ps) : QhullPoint(ps.dimension(), ps.coordinates()) {}
- explicit iterator(int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
- iterator & operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; }
- QhullPoint * operator->() { return this; }
- // value instead of reference since advancePoint() modifies self
- QhullPoint operator*() const { return *this; }
- QhullPoint operator[](int idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
- bool operator==(const iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates()==other.coordinates(); }
- bool operator!=(const iterator &other) const { return !operator==(other); }
- bool operator<(const iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() < other.coordinates(); }
- bool operator<=(const iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() <= other.coordinates(); }
- bool operator>(const iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() > other.coordinates(); }
- bool operator>=(const iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() >= other.coordinates(); }
- // reinterpret_cast to break circular dependency
- bool operator==(const QhullPoints::const_iterator &other) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(other).dimension()); return coordinates()==reinterpret_cast<const iterator &>(other).coordinates(); }
- bool operator!=(const QhullPoints::const_iterator &other) const { return !operator==(reinterpret_cast<const iterator &>(other)); }
- bool operator<(const QhullPoints::const_iterator &other) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(other).dimension()); return coordinates() < reinterpret_cast<const iterator &>(other).coordinates(); }
- bool operator<=(const QhullPoints::const_iterator &other) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(other).dimension()); return coordinates() <= reinterpret_cast<const iterator &>(other).coordinates(); }
- bool operator>(const QhullPoints::const_iterator &other) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(other).dimension()); return coordinates() > reinterpret_cast<const iterator &>(other).coordinates(); }
- bool operator>=(const QhullPoints::const_iterator &other) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(other).dimension()); return coordinates() >= reinterpret_cast<const iterator &>(other).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+=(int idx) { advancePoint(idx); return *this; }
- iterator & operator-=(int idx) { advancePoint(-idx); return *this; }
- iterator operator+(int idx) const { iterator n= *this; n.advancePoint(idx); return n; }
- iterator operator-(int idx) const { iterator n= *this; n.advancePoint(-idx); return n; }
- difference_type operator-(iterator other) const { QHULL_ASSERT(dimension()==other.dimension()); return (coordinates()-other.coordinates())/dimension(); }
- };//QhullPoints::iterator
-
-#//!\name QhullPoints::const_iterator -- FIXUP QH11018 const_iterator same as iterator
- 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() : QhullPoint() {}
- const_iterator(const const_iterator &other) : QhullPoint(*other) {}
- const_iterator(const QhullPoints::iterator &other) : QhullPoint(*other) {}
- explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.dimension(), ps.coordinates()) {}
- explicit const_iterator(int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
- const_iterator &operator=(const const_iterator &other) { defineAs(const_cast<const_iterator &>(other)); return *this; }
- // value/non-const since advancePoint(1), etc. modifies self
- QhullPoint operator*() const { return *this; }
- QhullPoint * operator->() { return this; }
- QhullPoint operator[](int idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
- bool operator==(const const_iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates()==other.coordinates(); }
- bool operator!=(const const_iterator &other) const { return !operator==(other); }
- bool operator<(const const_iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() < other.coordinates(); }
- bool operator<=(const const_iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() <= other.coordinates(); }
- bool operator>(const const_iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() > other.coordinates(); }
- bool operator>=(const const_iterator &other) const { QHULL_ASSERT(dimension()==other.dimension()); return coordinates() >= other.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+=(int idx) { advancePoint(idx); return *this; }
- const_iterator &operator-=(int idx) { advancePoint(-idx); return *this; }
- const_iterator operator+(int idx) const { const_iterator n= *this; n.advancePoint(idx); return n; }
- const_iterator operator-(int idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; }
- difference_type operator-(const_iterator other) const { QHULL_ASSERT(dimension()==other.dimension()); return (coordinates()-other.coordinates())/dimension(); }
- };//QhullPoints::const_iterator
-
-#//!\name IO
- struct PrintPoints{
- const QhullPoints *points;
- const char * point_message;
- int run_id;
- bool with_identifier;
- PrintPoints(int qhRunId, const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), run_id(qhRunId), with_identifier(withIdentifier) {}
- };//PrintPoints
- PrintPoints print() const { return PrintPoints(UsingLibQhull::NOqhRunId, "", false, *this); }
- PrintPoints print(int qhRunId) const { return PrintPoints(qhRunId, "", true, *this); }
- PrintPoints print(int qhRunId, const char *message) const { return PrintPoints(qhRunId, message, false, *this); }
- PrintPoints printWithIdentifier(int qhRunId, const char *message) const { return PrintPoints(qhRunId, message, true, *this); }
- //FIXUP remove message for print()?
-};//QhullPoints
-
-// can't use QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc would return a reference to a temporary
-class QhullPointsIterator
-{
- typedef QhullPoints::const_iterator const_iterator;
-
-private:
-#//!\name Fields
- 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/libqhullpcpp/QhullQh.cpp b/src/libqhullpcpp/QhullQh.cpp
deleted file mode 100644
index 74a706a..0000000
--- a/src/libqhullpcpp/QhullQh.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullQh.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
-
-
-
-#include "QhullError.h"
-#include "QhullQh.h"
-#include "QhullStat.h"
-
-#include <sstream>
-#include <iostream>
-
-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 {
-
-#//Global variables
-
-#//Constructor, destructor, etc.
-
-//! If qh_QHpointer==0, invoke with placement new on qh_qh;
-//! Sets qh_qh and qh_qhstat. Need to reset before UsingLibQhull.
-//! Derived from qh_new_qhull[user.c]
-QhullQh::
-QhullQh()
-{
- static boolT firstcall = True;
-
- if(firstcall){
- if(qhmem.BUFinit!=0){
- throw QhullError(10017, "Qhull error: qhmem already initialized by another class.");
- }
- qh_meminit(NULL);
- firstcall= False;
- }
- // QhullQh() and UsingLibQhull() are the same
-#if qh_QHpointer
- if(qh_qh){
- if(qh old_qhstat){
- throw QhullError(10041, "Qhull internal error: qh_qh.old_qhstat defined (%x) but qh_qh is active. qh_qh not restored correctly.", 0, 0, 0.0, qh old_qhstat);
- }
- qh old_qhstat= qh_qhstat;
- qh old_tempstack= qhmem.tempstack;
- qh_qhstat= 0;
- qhmem.tempstack= 0;
- }
- qh_qh= static_cast<qhT*>(this);
-#else
- if(strncmp(qh qhull, "qhull", 5) == 0){
- throw QhullError(10022, "Qhull error: Qhull already initialized as run %d", qh run_id);
- }
-#endif
- // NOerrors -- Does not call qh_errexit()
- qh_initstatistics();
- // NOerrors -- Does not call qh_errexit()
- qh_initqhull_start2(NULL, NULL, qh_FILEstderr);
-}//QhullQh
-
-//! UsingLibQhull must be declared along with QhullQh
-QhullQh::
-~QhullQh()
-{
-#if qh_QHpointer
- if(!qh_qh){
- QhullError e(10042, "Qhull internal error: qh_qh undefined. Was ~QhullQh() invoked independent of UsingLibQhull?", qh run_id, 0, 0, qh_qh);
- e.logError();
- }else if(!qh_qhstat){
- QhullError e(10043, "Qhull internal error: qh_qhstat null. Is another thread running?");
- e.logError();
- }else if(qh_qh!=this){
- QhullError e(10044, "Qhull error: ~QhullQh() invoked independent of UsingLibQhull. qh_qh %x (runId %d) vs. QhullQh.runId %d.", qh run_id, run_id, 0.0, qh_qh);
- e.logError();
- }else{
- qh_freeqhull2(qh_ALL); // sets qh.NOerrexit. Clears struct *qh_qh including run_id, but not qh_qh itself
- }
-#else
- if(&qh_qh!=this){
- QhullError e(10045, "Qhull error: ~QhullQh() invoked independent of UsingLibQhull. qh_qh %x (runId %d) vs. QhullQh.runId %d.", qh run_id, run_id, 0.0, qh_qh);
- e.logError();
- }else{
- qh_freeqhull2(qh_ALL); // sets qh.NOerrexit. Clears struct *qh_qh including run_id, but not qh_qh itself
- }
-#endif
-}//~QhullQh
-
-#//Parallel Access
-
-}//namespace orgQhull
-
diff --git a/src/libqhullpcpp/QhullQh.h b/src/libqhullpcpp/QhullQh.h
deleted file mode 100644
index 7995996..0000000
--- a/src/libqhullpcpp/QhullQh.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullQh.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLQH_H
-#define QHULLQH_H
-
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <string>
-#include <vector>
-
-namespace orgQhull {
-
-#//!\name defined here
- //! QhullQh -- Qhull's global data structure, qhT, as a C++ class
- //! See UsingLibQhull.h for C++/C interface to qhT
- class QhullQh;
-
-class QhullQh : public qhT {
-
-#//!\name Constants
- // Set ignored. PointSet needs explicit dimension
- // Facet from vertices or ridges.vertices.count
- // Ridge from vertices.count
- // Vertex stored in vertexT? 1->16?
- // QhullPoint needs explicit dimension
-
-#//!\name Fields
- //! No fields POD type equivalent to qhT. No data or virtual members
-
-public:
-#//!\name Constructors
- QhullQh();
- ~QhullQh();
-
-private:
- //!disable copy constructor and assignment
- QhullQh(const QhullQh &);
- QhullQh & operator=(const QhullQh &);
-
-};//class QhullQh
-
-}//namespace orgQhull
-
-#endif // QHULLQH_H
diff --git a/src/libqhullpcpp/QhullRidge.cpp b/src/libqhullpcpp/QhullRidge.cpp
deleted file mode 100644
index 912ba64..0000000
--- a/src/libqhullpcpp/QhullRidge.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullRidge.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
-
-#include "QhullSets.h"
-#include "QhullVertex.h"
-#include "QhullRidge.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 {
-
-#//class statics
-ridgeT QhullRidge::
-s_empty_ridge= {0,0,0,0,0,
- 0,0};
-
-#//Constructor, destructor, etc.
-
-#//Accessors
-
-//! Return True if nextRidge3d
-//! Simplicial facets may have incomplete ridgeSets
-//! Does not use qh_qh or qh_errexit()
-bool QhullRidge::
-hasNextRidge3d(const QhullFacet f) const
-{
- vertexT *v= 0;
- 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_qh or qh_errexit()
-QhullRidge QhullRidge::
-nextRidge3d(const QhullFacet f, QhullVertex *nextVertex) const
-{
- vertexT *v= 0;
- ridgeT *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(v);
- }
- return QhullRidge(ridge);
-}//nextRidge3d
-
-
-}//namespace orgQhull
-
-#//Global functions
-
-using std::endl;
-using std::ostream;
-using orgQhull::QhullRidge;
-using orgQhull::QhullVertex;
-using orgQhull::UsingLibQhull;
-
-ostream &
-operator<<(ostream &os, const QhullRidge &r)
-{
- os << r.print(UsingLibQhull::NOqhRunId);
- return os;
-}//<< QhullRidge
-
-//! Duplicate of qh_printridge [io.c]
-//! if pr.run_id==UsingLibQhull::NOqhRunId, no access to qh [needed for QhullVertex/QhullPoint]
-ostream &
-operator<<(ostream &os, const QhullRidge::PrintRidge &pr)
-{
- 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(pr.run_id, " 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/libqhullpcpp/QhullRidge.h b/src/libqhullpcpp/QhullRidge.h
deleted file mode 100644
index 840ca2b..0000000
--- a/src/libqhullpcpp/QhullRidge.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullRidge.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLRIDGE_H
-#define QHULLRIDGE_H
-
-#include "QhullSet.h"
-#include "QhullVertex.h"
-#include "QhullVertexSet.h"
-#include "QhullFacet.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name ClassRef
- class QhullVertex;
- class QhullVertexSet;
- class QhullFacet;
-
-#//!\name Types
- //! QhullRidge -- Qhull's ridge structure, ridgeT [libqhull.h], as a C++ class
- class QhullRidge;
- typedef QhullSet<QhullRidge> QhullRidgeSet;
- typedef QhullSetIterator<QhullRidge> 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 Fields
- ridgeT * qh_ridge;
-
-#//!\name Class objects
- static ridgeT s_empty_ridge;
-
-public:
-#//!\name Constants
-
-#//!\name Constructors
- QhullRidge() : qh_ridge(&s_empty_ridge) {}
- // Creates an alias. Does not copy QhullRidge. Needed for return by value and parameter passing
- QhullRidge(const QhullRidge &o) : qh_ridge(o.qh_ridge) {}
- // Creates an alias. Does not copy QhullRidge. Needed for vector<QhullRidge>
- QhullRidge & operator=(const QhullRidge &o) { qh_ridge= o.qh_ridge; return *this; }
- ~QhullRidge() {}
-
-#//!\name Conversion
- //Implicit conversion from ridgeT
- QhullRidge(ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge) {}
- ridgeT * getRidgeT() const { return qh_ridge; }
-
-#//!\name QhullSet<QhullRidge>
- ridgeT * getBaseT() const { return getRidgeT(); }
-
-#//!\name getSet
- QhullFacet bottomFacet() const { return QhullFacet(qh_ridge->bottom); }
- int dimension() const { return QhullSetBase::count(qh_ridge->vertices); }
- int id() const { return qh_ridge->id; }
- bool isDefined() const { return qh_ridge != &s_empty_ridge; }
- bool operator==(const QhullRidge &o) const { return qh_ridge==o.qh_ridge; }
- bool operator!=(const QhullRidge &o) const { return !operator==(o); }
- QhullFacet otherFacet(QhullFacet f) const { return QhullFacet(qh_ridge->top==f.getFacetT() ? qh_ridge->bottom : qh_ridge->top); }
- QhullFacet topFacet() const { return QhullFacet(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_ridge->vertices); }
-
-#//!\name IO
-
- struct PrintRidge{
- const QhullRidge *ridge;
- int run_id;
- PrintRidge(int qhRunId, const QhullRidge &r) : ridge(&r), run_id(qhRunId) {}
- };//PrintRidge
- PrintRidge print(int qhRunId) const { return PrintRidge(qhRunId, *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/libqhullpcpp/QhullSet.cpp b/src/libqhullpcpp/QhullSet.cpp
deleted file mode 100644
index 32dbacd..0000000
--- a/src/libqhullpcpp/QhullSet.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullSet.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullSet -- Qhull's set structure, setT, as a C++ class
-
-#include "QhullError.h"
-#include "QhullSet.h"
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//static members
-
-setT QhullSetBase::
-s_empty_set;
-
-// Same code for qh_setsize [qset.c] and QhullSetBase::count
-int QhullSetBase::count(const setT *set)
-{
- int 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;
-}
-
-
-}//namespace orgQhull
-
diff --git a/src/libqhullpcpp/QhullSet.h b/src/libqhullpcpp/QhullSet.h
deleted file mode 100644
index 46da38e..0000000
--- a/src/libqhullpcpp/QhullSet.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullSet.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QhullSet_H
-#define QhullSet_H
-
-#include "QhullError.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-
-#ifndef QHULL_NO_STL
-#include <vector>
-#endif
-
-#ifdef QHULL_USES_QT
- #include <QtCore/QList>
-#endif
-
-namespace orgQhull {
-
-#//!\name Type
- class QhullSetBase; //! Base class for QhullSet<T>
- //! QhullSet<T> -- A read-only wrapper to Qhull's collection class, setT.
- //! QhullSet is similar to STL's <vector> and Qt's QVector.
- //! QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
- //! For STL efficiency, QhullSet caches endPointer()
- //! T must be a pointer type
- //! A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
- //! Qhull's FOREACHelement_() [qset.h] is 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/qvector.h
-
- //! QhullSetIterator<T> defined below
- //See: QhullPointSet, QhullLinkedList<T>
-
-class QhullSetBase {
-
-private:
-#//!\name Fields --
- setT * qh_set;
-
-#//!\name Class objects
- static setT s_empty_set; //! Workaround for no setT allocator. Used if setT* is NULL
-
-public:
-#//!\name Class methods
- static int count(const setT *set);
- //s may be null
- static bool isEmpty(const setT *s) { return SETempty_(s); }
-
-
-#//!\name Constructors
- //! Copy constructor copies the pointer but not the set. Needed for return by value and parameter passing.
- QhullSetBase(const QhullSetBase &o) : qh_set(o.qh_set) {}
- explicit QhullSetBase(setT *s) : qh_set(s ? s : &s_empty_set) {}
- ~QhullSetBase() {}
-
-private:
- //!disabled since memory allocation for QhullSet not defined
- QhullSetBase() {}
- //!disabled since qs= qs2 is ambiguous (pointer vs. contents)
- QhullSetBase & operator=(const QhullSetBase &);
-public:
-
-#//!\name Conversions
- //! Not type-safe since setT may contain any type
- void defineAs(setT *s) { qh_set= s ? s : &s_empty_set; }
- setT * getSetT() const { return qh_set; }
- setT ** referenceSetT() { return &qh_set; }
-
-#//!\name Read-only
- int count() const { return QhullSetBase::count(qh_set); }
- bool empty() const { return SETfirst_(qh_set)==0; }
- bool isEmpty() const { return empty(); }
- size_t size() const { return count(); }
-
-#//!\name Element
-protected:
- void ** beginPointer() const { return &qh_set->e[0].p; }
- void ** elementPointer(int idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
- //! Always points to 0
- void ** endPointer() const { return qh_setendpointer(qh_set); }
-};//QhullSetBase
-
-
-//! set of pointers to baseT, T.getBaseT()
-template <typename T>
-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 Subtypes
- typedef T * iterator;
- typedef const T * const_iterator;
- typedef typename QhullSet<T>::iterator Iterator;
- typedef typename QhullSet<T>::const_iterator ConstIterator;
-
-#//!\name Class methods
- static int count(const setT *set);
- //s may be null
- static bool isEmpty(const setT *s) { return SETempty_(s); }
-
-#//!\name Constructors
- //Copy constructor copies pointer but not contents. Needed for return by value.
- QhullSet<T>(const QhullSet<T> &o) : QhullSetBase(o) {}
- //Conversion from setT* is not type-safe. Implicit conversion for void* to T
- explicit QhullSet<T>(setT *s) : QhullSetBase(s) { QHULL_ASSERT(sizeof(T)==sizeof(void *)); }
- ~QhullSet<T>() {}
-
-private:
- //!Disable default constructor and copy assignment. See QhullSetBase
- QhullSet<T>();
- QhullSet<T> & operator=(const QhullSet<T> &);
-public:
-
-#//!\name Conversion
-
-#ifndef QHULL_NO_STL
- std::vector<T> toStdVector() const;
-#endif
-#ifdef QHULL_USES_QT
- QList<T> toQList() const;
-#endif
-
-#//!\name Read-only -- 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<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
- bool operator!=(const QhullSet<T> &other) const { return !operator==(other); }
-
-#//!\name Element access
- const T & at(int idx) const { return operator[](idx); }
- T & back() { return last(); }
- T & back() const { return last(); }
- //! end element is NULL
- const T * constData() const { return constBegin(); }
- T * data() { return begin(); }
- const T * data() const { return begin(); }
- T & first() { QHULL_ASSERT(!isEmpty()); return *begin(); }
- const T & first() const { QHULL_ASSERT(!isEmpty()); return *begin(); }
- T & front() { return first(); }
- const T & front() const { return first(); }
- T & last() { QHULL_ASSERT(!isEmpty()); return *(end()-1); }
- const T & last() const { QHULL_ASSERT(!isEmpty()); return *(end()-1); }
- // mid() not available. No setT constructor
- T & operator[](int idx) { T *n= reinterpret_cast<T *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; }
- const T & operator[](int idx) const { const T *n= reinterpret_cast<const T *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; }
- T & second() { return operator[](1); }
- const T & second() const { return operator[](1); }
- T value(int idx) const;
- T value(int idx, const T &defaultValue) const;
-
-#//!\name GetSet -- Not available, no setT constructor
-
-#//!\name iterator
- iterator begin() { return iterator(beginPointer()); }
- const_iterator begin() const { return const_iterator(beginPointer()); }
- const_iterator constBegin() const { return const_iterator(beginPointer()); }
- const_iterator constEnd() const { return const_iterator(endPointer()); }
- iterator end() { return iterator(endPointer()); }
- const_iterator end() const { return const_iterator(endPointer()); }
-
-#//!\name Search
- bool contains(const T &t) const;
- int count(const T &t) const;
- int indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
- int lastIndexOf(const T &t) const;
-
-};//class QhullSet
-
-// FIXUP? can't use QHULL_DECLARE_SEQUENTIAL_ITERATOR because it is not a template
-
-template <typename T>
-class QhullSetIterator {
-
-#//!\name Subtypes
- typedef typename QhullSet<T>::const_iterator const_iterator;
-
-private:
-#//!\name Fields
- const_iterator i;
- const_iterator begin_i;
- const_iterator end_i;
-
-public:
-#//!\name Constructors
- QhullSetIterator<T>(const QhullSet<T> &s) : i(s.begin()), begin_i(i), end_i(s.end()) {}
- QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i) {}
- QhullSetIterator<T> &operator=(const QhullSetIterator<T> &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; return *this; }
-
-#//!\name ReadOnly
- int countRemaining() { return (int)(end_i-begin_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 *i++; }
- T peekNext() const { return *i; }
- T peekPrevious() const { const_iterator p = i; return *--p; }
- T previous() { return *--i; }
- void toBack() { i = end_i; }
- void toFront() { i = begin_i; }
-};//class QhullSetIterator
-
-#//!\name Conversion
-
-#ifndef QHULL_NO_STL
-template <typename T>
-std::vector<T> QhullSet<T>::
-toStdVector() const
-{
- QhullSetIterator<T> i(*this);
- std::vector<T> vs;
- vs.reserve(i.countRemaining());
- while(i.hasNext()){
- vs.push_back(i.next());
- }
- return vs;
-}//toStdVector
-#endif
-
-#ifdef QHULL_USES_QT
-template <typename T>
-QList<T> QhullSet<T>::
-toQList() const
-{
- QhullSetIterator<T> i(*this);
- QList<T> vs;
- while(i.hasNext()){
- vs.append(i.next());
- }
- return vs;
-}//toQList
-#endif
-
-#//!\name Element
-
-template <typename T>
-T QhullSet<T>::
-value(int idx) const
-{
- // Avoid call to qh_setsize() and assert in elementPointer()
- const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
- return (idx>=0 && n<end()) ? *n : T();
-}//value
-
-template <typename T>
-T QhullSet<T>::
-value(int idx, const T &defaultValue) const
-{
- // Avoid call to qh_setsize() and assert in elementPointer()
- const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
- return (idx>=0 && n<end()) ? *n : defaultValue;
-}//value
-
-#//!\name Search
-
-template <typename T>
-bool QhullSet<T>::
-contains(const T &t) const
-{
- setT *s= getSetT();
- void *e= t.getBaseT(); // contains() is not inline for better error reporting
- int result= qh_setin(s, e);
- return result!=0;
-}//contains
-
-template <typename T>
-int QhullSet<T>::
-count(const T &t) const
-{
- int c= 0;
- const T *i= data();
- const T *e= end();
- while(i<e){
- if(*i==t){
- c++;
- }
- i++;
- }
- return c;
-}//count
-
-template <typename T>
-int QhullSet<T>::
-lastIndexOf(const T &t) const
-{
- const T *b= begin();
- const T *i= end();
- while(--i>=b){
- if(*i==t){
- break;
- }
- }
- return (int)(i-b); // WARN64
-}//lastIndexOf
-
-#//!\name QhullSetIterator
-
-template <typename T>
-bool QhullSetIterator<T>::
-findNext(const T &t)
-{
- while(i!=end_i){
- if(*(++i)==t){
- return true;
- }
- }
- return false;
-}//findNext
-
-template <typename T>
-bool QhullSetIterator<T>::
-findPrevious(const T &t)
-{
- while(i!=begin_i){
- if(*(--i)==t){
- return true;
- }
- }
- return false;
-}//findPrevious
-
-}//namespace orgQhull
-
-
-#//!\name Global
-
-template <typename T>
-std::ostream &
-operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
-{
- const T *i= qs.begin();
- const T *e= qs.end();
- while(i!=e){
- os << *i;
- ++i;
- }
- return os;
-}//operator<<
-
-#endif // QhullSet_H
diff --git a/src/libqhullpcpp/QhullSets.h b/src/libqhullpcpp/QhullSets.h
deleted file mode 100644
index f3d7d65..0000000
--- a/src/libqhullpcpp/QhullSets.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullSets.h#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLSETS_H
-#define QHULLSETS_H
-
-#include "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<QhullRidge> QhullRidgeSet;
- typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
-
-}//namespace orgQhull
-
-#endif // QHULLSETS_H
diff --git a/src/libqhullpcpp/QhullStat.cpp b/src/libqhullpcpp/QhullStat.cpp
deleted file mode 100644
index 68a1326..0000000
--- a/src/libqhullpcpp/QhullStat.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullStat.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullStat -- Qhull's global data structure, statT, as a C++ class
-
-
-#include "QhullError.h"
-#include "QhullStat.h"
-
-#include <sstream>
-#include <iostream>
-
-using std::cerr;
-using std::string;
-using std::vector;
-using std::ostream;
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//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/libqhullpcpp/QhullStat.h b/src/libqhullpcpp/QhullStat.h
deleted file mode 100644
index aa94575..0000000
--- a/src/libqhullpcpp/QhullStat.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullStat.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLSTAT_H
-#define QHULLSTAT_H
-
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <string>
-#include <vector>
-
-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
- //! No fields POD type equivalent to qhstatT. No data or virtual members
-
-public:
-#//!\name Constants
-
-#//!\name class methods
- static void clearStatistics();
-
-#//!\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/libqhullpcpp/QhullVertex.cpp b/src/libqhullpcpp/QhullVertex.cpp
deleted file mode 100644
index 24fdfe3..0000000
--- a/src/libqhullpcpp/QhullVertex.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullVertex.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class
-
-#include "UsingLibQhull.h"
-#include "QhullPoint.h"
-#include "QhullFacetSet.h"
-#include "QhullVertex.h"
-#include "QhullVertexSet.h"
-#include "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 {
-
-#//class statics
-vertexT QhullVertex::
-s_empty_vertex= {0,0,0,0,0,
- 0,0,0,0,0,
- 0,0};
-
-#//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_vertex->neighbors);
-}//neighborFacets
-
-}//namespace orgQhull
-
-#//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;
-using orgQhull::UsingLibQhull;
-
-//! Duplicate of qh_printvertex [io.c]
-ostream &
-operator<<(ostream &os, const QhullVertex::PrintVertex &pr)
-{
- QhullVertex v= *pr.vertex;
- QhullPoint p= v.point();
- os << "- p" << p.id(pr.run_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:";
- int 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/libqhullpcpp/QhullVertex.h b/src/libqhullpcpp/QhullVertex.h
deleted file mode 100644
index 5b88566..0000000
--- a/src/libqhullpcpp/QhullVertex.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullVertex.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLVERTEX_H
-#define QHULLVERTEX_H
-
-#include "UsingLibQhull.h"
-#include "QhullPoint.h"
-#include "QhullLinkedList.h"
-#include "QhullSet.h"
-extern "C" {
- #include "libqhull/qhull_a.h"
-}
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name ClassRef
- class QhullFacetSet;
-
-#//!\name Types
- //! QhullVertex -- Qhull's vertex structure, vertexT [libqhull.h], as a C++ class
- class QhullVertex;
- typedef QhullLinkedList<QhullVertex> QhullVertexList;
- typedef QhullLinkedListIterator<QhullVertex> 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 {
-
-private:
-#//!\name Fields
- vertexT * qh_vertex;
-
-#//!\name Class objects
- static vertexT s_empty_vertex; // needed for shallow copy
-
-public:
-#//!\name Constants
-
-#//!\name Constructors
- QhullVertex() : qh_vertex(&s_empty_vertex) {}
- // Creates an alias. Does not copy QhullVertex. Needed for return by value and parameter passing
- QhullVertex(const QhullVertex &o) : qh_vertex(o.qh_vertex) {}
- // Creates an alias. Does not copy QhullVertex. Needed for vector<QhullVertex>
- QhullVertex & operator=(const QhullVertex &o) { qh_vertex= o.qh_vertex; return *this; }
- ~QhullVertex() {}
-
-#//!\name Conversion
- //Implicit conversion from vertexT
- QhullVertex(vertexT *v) : qh_vertex(v ? v : &s_empty_vertex) {}
- vertexT * getVertexT() const { return qh_vertex; }
- vertexT * getBaseT() const { return getVertexT(); }
-
-#//!\name getSet
- int dimension() const { return (qh_vertex->dim || !isDefined()) ? qh_vertex->dim : UsingLibQhull::globalVertexDimension(); }
- int id() const { return qh_vertex->id; }
- bool isDefined() const { return 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 qh_vertex->next; }
- bool operator==(const QhullVertex &o) const { return qh_vertex==o.qh_vertex; }
- bool operator!=(const QhullVertex &o) const { return !operator==(o); }
- QhullPoint point() const { return QhullPoint(dimension(), qh_vertex->point); }
- QhullVertex previous() const { return qh_vertex->previous; }
-
-#//!\name ForEach
- //See also QhullVertexList
- QhullFacetSet neighborFacets() const;
-
-#//!\name IO
- struct PrintVertex{
- const QhullVertex *vertex;
- int run_id;
- PrintVertex(int qhRunId, const QhullVertex &v) : vertex(&v), run_id(qhRunId) {}
- };//PrintVertex
- PrintVertex print(int qhRunId) const { return PrintVertex(qhRunId, *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(orgQhull::UsingLibQhull::NOqhRunId); return os; }
-
-#endif // QHULLVERTEX_H
diff --git a/src/libqhullpcpp/QhullVertexSet.cpp b/src/libqhullpcpp/QhullVertexSet.cpp
deleted file mode 100644
index 09e3365..0000000
--- a/src/libqhullpcpp/QhullVertexSet.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullVertexSet.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! QhullVertexSet -- Qhull's linked Vertexs, as a C++ class
-
-#include "QhullVertex.h"
-#include "QhullVertexSet.h"
-#include "QhullPoint.h"
-#include "QhullRidge.h"
-#include "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 */
- /* setjmp should not be implemented with 'catch' */
-#endif
-
-namespace orgQhull {
-
-QhullVertexSet::
-QhullVertexSet(int qhRunId, facetT *facetlist, setT *facetset, bool allfacets)
-: QhullSet<QhullVertex>(0)
-, qhsettemp_qhull(0)
-, qhsettemp_defined(false)
-{
- UsingLibQhull q(qhRunId);
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- setT *vertices= qh_facetvertices(facetlist, facetset, allfacets);
- defineAs(vertices);
- qhsettemp_qhull= s_qhull_output;
- qhsettemp_defined= true;
- }
- q.maybeThrowQhullMessage(exitCode);
-}//QhullVertexSet facetlist facetset
-
-void QhullVertexSet::
-freeQhSetTemp()
-{
- if(qhsettemp_defined){
- UsingLibQhull q(qhsettemp_qhull, QhullError::NOthrow);
- if(q.defined()){
- int exitCode = setjmp(qh errexit);
- if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- qh_settempfree(referenceSetT()); // errors if not top of tempstack or if qhmem corrupted
- }
- q.maybeThrowQhullMessage(exitCode, QhullError::NOthrow);
- }
- }
-}//freeQhSetTemp
-
-QhullVertexSet::
-~QhullVertexSet()
-{
- freeQhSetTemp();
-}//~QhullVertexSet
-
-}//namespace orgQhull
-
-#//Global functions
-
-using std::endl;
-using std::ostream;
-using orgQhull::QhullPoint;
-using orgQhull::QhullVertex;
-using orgQhull::QhullVertexSet;
-using orgQhull::QhullVertexSetIterator;
-using orgQhull::UsingLibQhull;
-
-//! Print Vertex identifiers to stream. Space prefix. From qh_printVertexheader [io.c]
-ostream &
-operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr)
-{
- if(pr.print_message && *pr.print_message){
- 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;
-}//<<QhullVertexSet::PrintIdentifiers
-
-//! Duplicate of printvertices [io.c]
-//! If pr.run_id==UsingLibQhull::NOqhRunId, no access to qh [needed for QhullPoint]
-ostream &
-operator<<(ostream &os, const QhullVertexSet::PrintVertexSet &pr){
-
- os << pr.print_message;
- const QhullVertexSet *vs= pr.Vertex_set;
- QhullVertexSetIterator i= *vs;
- while(i.hasNext()){
- const QhullVertex v= i.next();
- const QhullPoint p= v.point();
- os << " p" << p.id(pr.run_id) << "(v" << v.id() << ")";
- }
- os << endl;
-
- return os;
-}//<< PrintVertexSet
-
-
diff --git a/src/libqhullpcpp/QhullVertexSet.h b/src/libqhullpcpp/QhullVertexSet.h
deleted file mode 100644
index 78b28ea..0000000
--- a/src/libqhullpcpp/QhullVertexSet.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/QhullVertexSet.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHULLVERTEXSET_H
-#define QHULLVERTEXSET_H
-
-#include "QhullSet.h"
-
-#include <ostream>
-
-namespace orgQhull {
-
-#//!\name ClassRef
- class QhullVertex;
-
-#//!\name Types
- //! QhullVertexSet -- a set of Qhull Vertices, as a C++ class.
- //! See Qhull
- class QhullVertexSet;
- typedef QhullSetIterator<QhullVertex>
- QhullVertexSetIterator;
-
-class QhullVertexSet : public QhullSet<QhullVertex> {
-
-private:
-#//!\name Fields
- Qhull * qhsettemp_qhull; //! For sets allocated with qh_settemp()
- bool qhsettemp_defined; //! Set was allocated with q_memalloc()
-
-public:
-#//!\name Constructor
- //Conversion from setT* is not type-safe. Implicit conversion for void* to T
- explicit QhullVertexSet(setT *s) : QhullSet<QhullVertex>(s), qhsettemp_qhull(0), qhsettemp_defined(false) {}
- QhullVertexSet(int qhRunId, facetT *facetlist, setT *facetset, bool allfacets);
- //Copy constructor copies pointer but not contents. Needed for return by value.
- QhullVertexSet(const QhullVertexSet &o) : QhullSet<QhullVertex>(o), qhsettemp_qhull(o.qhsettemp_qhull), qhsettemp_defined(o.qhsettemp_defined) {}
- ~QhullVertexSet();
-
-private:
- //!Disable default constructor and copy assignment. See QhullSetBase
- QhullVertexSet();
- QhullVertexSet & operator=(const QhullVertexSet &);
-public:
-
-#//!\name Constructor, destructor
- void freeQhSetTemp();
-
-#//!\name IO
- struct PrintVertexSet{
- const QhullVertexSet *Vertex_set;
- const char * print_message;
- int run_id;
- PrintVertexSet(int qhRunId, const char *message, const QhullVertexSet *s) : Vertex_set(s), print_message(message), run_id(qhRunId) {}
- };//PrintVertexSet
- const PrintVertexSet print(int qhRunId, const char *message) const { return PrintVertexSet(qhRunId, message, this); }
-
- struct PrintIdentifiers{
- const QhullVertexSet *Vertex_set;
- const char * print_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(orgQhull::UsingLibQhull::NOqhRunId, ""); return os; }
-
-#endif // QHULLVERTEXSET_H
diff --git a/src/libqhullpcpp/RboxPoints.cpp b/src/libqhullpcpp/RboxPoints.cpp
deleted file mode 100644
index d62f9a3..0000000
--- a/src/libqhullpcpp/RboxPoints.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/RboxPoints.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include "QhullError.h"
-#include "RboxPoints.h"
-
-#include <iostream>
-
-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)
-
-#//Global
-
-//! pointer to RboxPoints for qh_fprintf callback
-RboxPoints *rbox_output= 0;
-
-#//Construct
-RboxPoints::
-RboxPoints()
-: PointCoordinates("rbox")
-, rbox_new_count(0)
-, rbox_status(qh_ERRnone)
-, rbox_message()
-{}
-
-RboxPoints::
-RboxPoints(const char *rboxCommand)
-: PointCoordinates("rbox ")
-, rbox_new_count(0)
-, rbox_status(qh_ERRnone)
-, rbox_message()
-{
- std::string s= comment() + rboxCommand;
- setComment(s);
- appendPoints(rboxCommand);
-}
-
-RboxPoints::
-RboxPoints(const RboxPoints &other)
-: PointCoordinates(other)
-, rbox_new_count(0)
-, rbox_status(other.rbox_status)
-, rbox_message(other.rbox_message)
-{}
-
-RboxPoints & RboxPoints::
-operator=(const RboxPoints &other)
-{
- PointCoordinates::operator=(other);
- rbox_new_count= other.rbox_new_count;
- rbox_status= other.rbox_status;
- rbox_message= other.rbox_message;
- return *this;
-}//operator=
-
-
-RboxPoints::
-~RboxPoints()
-{}
-
-#//Error
-
-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);
-}
-
-#//Modify
-
-void RboxPoints::
-appendPoints(const char *rboxCommand)
-{
- string s("rbox ");
- s += rboxCommand;
- char *command= const_cast<char*>(s.c_str());
- if(rbox_output){
- throw QhullError(10001, "Qhull error: Two simultaneous calls to RboxPoints::appendPoints(). Prevent two processes calling appendPoints() at the same time. Other RboxPoints '%s'", 0, 0, 0, rbox_output->comment().c_str());
- }
- 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());
- }
- int previousCount= count();
- rbox_output= this; // set rbox_output for qh_fprintf()
- int status= ::qh_rboxpoints(0, 0, command);
- rbox_output= 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
-
-#//Global functions
-
-/*-<a href="qh-user.htm#TOC"
->-------------------------------</a><a name="qh_fprintf_rbox">-</a>
-
- qh_fprintf_rbox(fp, msgcode, format, list of args )
- fp is ignored (replaces qh_fprintf_rbox() in userprintf_rbox.c)
- rbox_output == 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;
-*/
-extern "C"
-void qh_fprintf_rbox(FILE*, int msgcode, const char *fmt, ... ) {
- va_list args;
-
- using namespace orgQhull;
-
- if(!qh->rbox_output){
- // No place to write an error message
- qh_errexit_rbox(10072);
- }
- RboxPoints *out= rbox_output;
- va_start(args, fmt);
- if(msgcode<MSG_OUTPUT){
- char newMessage[MSG_MAXLEN];
- // RoadError provides the message tag
- vsnprintf(newMessage, sizeof(newMessage), fmt, args);
- out->rbox_message += newMessage;
- if(out->rbox_status<MSG_ERROR || out->rbox_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(10010);
- /* never returns */
- case 9393:
- {
- int dimension= va_arg(args, int);
- string command(va_arg(args, char*));
- int count= va_arg(args, int);
- 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/libqhullpcpp/RboxPoints.h b/src/libqhullpcpp/RboxPoints.h
deleted file mode 100644
index df7ff80..0000000
--- a/src/libqhullpcpp/RboxPoints.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/RboxPoints.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef RBOXPOINTS_H
-#define RBOXPOINTS_H
-
-#include "QhullPoint.h"
-#include "PointCoordinates.h"
-extern "C" {
-#include "libqhull/libqhull.h"
-}
-
-#include <stdarg.h>
-#include <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <sstream>
-
-namespace orgQhull {
-
-#//!\name Types
- //! RboxPoints -- generate random PointCoordinates for Qhull
- class RboxPoints;
-
-class RboxPoints : public PointCoordinates {
-
-private:
-#//!\name Fields and friends
- int 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
-
- friend void ::qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
-
-public:
-#//!\name Construct
- RboxPoints();
- explicit RboxPoints(const char *rboxCommand);
- RboxPoints(const RboxPoints &other);
- RboxPoints &operator=(const RboxPoints &other);
- ~RboxPoints();
-
-public:
-#//!\name GetSet
- void clearRboxMessage();
- int newCount() const { return rbox_new_count; }
- std::string rboxMessage() const;
- int rboxStatus() const;
- bool hasRboxMessage() const;
- void setNewCount(int 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/libqhullpcpp/RoadError.cpp b/src/libqhullpcpp/RoadError.cpp
deleted file mode 100644
index f54727f..0000000
--- a/src/libqhullpcpp/RoadError.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/RoadError.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
-#//! Do not throw RoadError's from destructors. Use e.logError() instead.
-
-#include "RoadError.h"
-
-#include <string>
-#include <sstream>
-#include <iostream>
-
-using std::cerr;
-using std::cout;
-using std::string;
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//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;
-
-#//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=
-
-#//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
-
-#//Updates
-
-//! Log error instead of throwing it.
-void RoadError::
-logError() const
-{
- global_log << what() << endl;
-}//logError
-
-
-}//namespace orgQhull
-
diff --git a/src/libqhullpcpp/RoadError.h b/src/libqhullpcpp/RoadError.h
deleted file mode 100644
index bbfa508..0000000
--- a/src/libqhullpcpp/RoadError.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/RoadError.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef ROADERROR_H
-#define ROADERROR_H
-
-#include "RoadLogEvent.h"
-
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-#include <string>
-
-using std::endl;
-
-namespace orgQhull {
-
-#//!\name Types
- //! 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
-
-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 isDefined() const { return log_event.isDefined(); }
- int errorCode() const { return error_code; };
- // FIXUP QH11021 should RoadError provide errorMessage(). Currently what()
- RoadLogEvent roadLogEvent() const { return log_event; };
-
-#//!\name Update
- void logError() 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/libqhullpcpp/RoadLogEvent.cpp b/src/libqhullpcpp/RoadLogEvent.cpp
deleted file mode 100644
index 0847eb3..0000000
--- a/src/libqhullpcpp/RoadLogEvent.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/RoadLogEvent.cpp#2 $$Change: 1810 $
-** $Date: 2015/01/17 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
-
-#include "RoadError.h"
-
-#include <string>
-#include <sstream>
-#include <iostream>
-
-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
-
-#//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/libqhullpcpp/RoadLogEvent.h b/src/libqhullpcpp/RoadLogEvent.h
deleted file mode 100644
index 1a8fa31..0000000
--- a/src/libqhullpcpp/RoadLogEvent.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/RoadLogEvent.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef ROADLOGEVENT_H
-#define ROADLOGEVENT_H
-
-#include <ostream>
-#include <stdexcept>
-#include <string>
-
-namespace orgQhull {
-
-#//!\name Types
- //! 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 isDefined() 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/libqhullpcpp/UsingLibQhull.cpp b/src/libqhullpcpp/UsingLibQhull.cpp
deleted file mode 100644
index 7476c98..0000000
--- a/src/libqhullpcpp/UsingLibQhull.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/UsingLibQhull.cpp#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#//! UsingLibQhull -- Set up qhull C code from C++
-
-#include "Qhull.h"
-#include "UsingLibQhull.h"
-#include "QhullError.h"
-#include "QhullQh.h"
-
-#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
-#endif
-
-namespace orgQhull {
-
-#//Class objects
-
-const double UsingLibQhull::
-DEFAULTdistanceEpsilon= 1e-15*FACTORepsilon; //! ~DISTround*FACTORepsilon for unit cube
-
-const double UsingLibQhull::
-DEFAULTangleEpsilon= 1e-15*FACTORepsilon; //! ~ANGLEround*FACTORepsilon for unit cube
-
- //! Global pointer to Qhull for qh_fprintf callback and QhullError
-Qhull *
-s_qhull_output= 0;
-
-double UsingLibQhull::
-s_angle_epsilon= 0;
-
-double UsingLibQhull::
-s_distance_epsilon= 0;
-
-//! For QhullPoint.id() w/o qhRunId. Initialized by Qhull
-const coordT *UsingLibQhull::
-s_points_begin= 0;
-const coordT *UsingLibQhull::
-s_points_end= 0;
-int UsingLibQhull::
-s_points_dimension= 0;
-
-int UsingLibQhull::
-s_vertex_dimension= 0; // FIXUP QH11023: s_vertex_dimension is required if dimension>15. Cannot store in QhullVertex
-
-bool UsingLibQhull::
-s_has_points= false;
-
-bool UsingLibQhull::
-s_has_angle_epsilon= false;
-
-bool UsingLibQhull::
-s_has_vertex_dimension= false;
-
-bool UsingLibQhull::
-s_has_distance_epsilon= false;
-
-bool UsingLibQhull::
-s_using_libqhull= false;
-
-#//Constructors
-
-//! Grabs global state (qh_qh, qh_qhstat, qhmem.tempstack)
-//! Follow immediately with setjmp(qh errexit), otherwise errors in libqhull are not caught properly
-//! See qh_restore_qhull [global.c]
-UsingLibQhull::
-UsingLibQhull(Qhull *q)
-: my_qhull(q)
-, qh_exitcode(0)
-{
- checkUsingLibQhull();
- QhullQh *qhullqh= q->qhullQh();
- if(!qhullqh){
- throw QhullError(10014, "Qhull internal error: Qhull.qhullQh() not defined. initializeQhull() not called.");
- }
- if(qhullqh->run_id != q->qhull_run_id){
- throw QhullError(10015, "Qhull error: QhullQh.runId %d != Qhull.runId %d. Overwritten?", qhullqh->run_id, q->qhull_run_id);
- }
- // qh.old_qhstat is zero at initialization
- // qh.old_tempstack is zero when empty
- // QhullQh() and UsingLibQhull() are the same
-#if qh_QHpointer
- if(qh_qh){
- qh old_qhstat= qh_qhstat;
- qh old_tempstack= qhmem.tempstack;
- }
- qh_qh= qhullqh;
- qh_qhstat= qhullqh->old_qhstat;
- qhmem.tempstack= qhullqh->old_tempstack;
- qhullqh->old_qhstat= 0;
- qhullqh->old_tempstack= 0;
-#else
- #error FIXUP QH11024 static qh_qh not tested. Delete the line to try.
- if(qhullqh!=&qh_qh){
- throw QhullError(10040, "Qhull internal error: Qhull.qhullQh() is not qh_qh (%x, static). Overwrite?", 0,0,0.0, &qh_qh);
- }
-#endif
- s_qhull_output= q; // set s_qhull_output for qh_fprintf()
- qh NOerrexit= False; // assumes setjmp called next
-}//UsingLibQhull qhull
-
-//! Same as UsingLibQhull but does not throw exceptions
-//! !defined() on failure. For use in destructors
-UsingLibQhull::
-UsingLibQhull(Qhull *q, int noThrow)
-: my_qhull(0) // Fail by default
-, qh_exitcode(0)
-{
- QHULL_UNUSED(noThrow);
-
- QhullQh *qhullqh= q->qhullQh();
- if(s_using_libqhull){
- QhullError e(10050, "Qhull error: UsingLibQhull already in use");
- e.logError();
- }else if(!qhullqh || qhullqh->run_id != q->qhull_run_id){
- QhullError e(10051, "Qhull error: Qhull.qhullQh (%x) undefined or QhullQh.runId %d != Qhull.runId %d. Overwritten?", (qhullqh ? qhullqh->run_id : -1), q->qhull_run_id, 0.0, qhullqh);
- e.logError();
- }else{
- // qh.old_qhstat is zero at initialization
- // qh.old_tempstack is zero when empty
- // QhullQh() and UsingLibQhull() are the same
-#if qh_QHpointer
- if(qh_qh){
- qh old_qhstat= qh_qhstat;
- qh old_tempstack= qhmem.tempstack;
- }
- qh_qh= qhullqh;
- qh_qhstat= qhullqh->old_qhstat;
- qhmem.tempstack= qhullqh->old_tempstack;
- qhullqh->old_qhstat= 0;
- qhullqh->old_tempstack= 0;
-#endif
- my_qhull= q;
- s_qhull_output= q; // set s_qhull_output for qh_fprintf()
- qh NOerrexit= False; // assumes setjmp called next
- }
-}//UsingLibQhull qhull noThrow
-
-//! Reuses current global state (qh_qh) from prior UsingQhull
-//! Errors if runId is not the same
-UsingLibQhull::
-UsingLibQhull(int qhRunId)
-: my_qhull(0)
-, qh_exitcode(0)
-{
- checkUsingLibQhull();
-#if qh_QHpointer
- if(!qh_qh || !qh_qhstat){
- throw QhullError(10024, "Qhull error: UsingLibQhull is not active (qh_qh %x or qh_qhstat is not defined)", 0,0,0.0, qh_qh);
- }
-#endif
- if(qh run_id!=qhRunId){
- throw QhullError(10036, "Qhull error: qhRunId %d != qh_qh.runId %d. Is another Qhull active?", qhRunId, qh run_id);
- }
- if(!s_qhull_output){
- throw QhullError(10037, "Qhull error: UsingLibQhull not active(s_qhull_output undefined). Invoke UsingLibQhull before this call");
- }
- if(s_qhull_output->qhull_run_id!=qhRunId){
- throw QhullError(10046, "Qhull error: qhRunId %d != s_qhull_output.runId %d. Is another Qhull active", qhRunId, s_qhull_output->qhull_run_id);
- }
- my_qhull= s_qhull_output;
- qh NOerrexit= False; // assumes setjmp called next
-}//UsingLibQhull runId
-
-//Leaves libqhull active for runId access
-UsingLibQhull::
-~UsingLibQhull()
-{
- QhullError e= checkRunId();
- if(e.isDefined()){
- e.logError();
- }else{
-#if qh_QHpointer
- if(qh_qh){
- qh NOerrexit= true;
- }
-#else
- qh NOerrexit= true;
-#endif
- }
- s_using_libqhull= false;
-}//~UsingLibQhull
-
-#//Class methods
-
-void UsingLibQhull::
-checkQhullMemoryEmpty()
-{
- int curlong, totlong, curshort, totshort, maxlong, totbuffer;
- // qh_memtotal does not error
- qh_memtotal(&curlong, &totlong, &curshort, &totshort, &maxlong, &totbuffer);
- if (curlong || totlong){
- throw QhullError(10026, "Qhull error: qhull did not free %d bytes of long memory (%d pieces).", totlong, curlong);
- }
- if (curshort || totshort){
- throw QhullError(10035, "Qhull error: qhull did not free %d bytes of short memory (%d pieces).", totshort, curshort);
- }
-}//checkQhullMemoryEmpty
-
-//! Epsilon for distance to hyperplane angle equality
-double UsingLibQhull::
-currentAngleEpsilon()
-{
- if(s_qhull_output && s_qhull_output->initialized()){
- return s_qhull_output->qhullQh()->ANGLEround*FACTORepsilon;
- }else if(s_has_angle_epsilon){
- return s_angle_epsilon;
- }
- return UsingLibQhull::DEFAULTangleEpsilon;
-}//currentAngleEpsilon
-
-//! Epsilon for distance to hyperplane
-double UsingLibQhull::
-currentDistanceEpsilon()
-{
- if(s_qhull_output && s_qhull_output->initialized()){
- return s_qhull_output->qhullQh()->DISTround*FACTORepsilon;
- }else if(s_has_distance_epsilon){
- return s_distance_epsilon;
- }
- return UsingLibQhull::DEFAULTdistanceEpsilon;
-}//currentDistanceEpsilon
-
-const coordT *UsingLibQhull::
-currentPoints(int *dimension, const coordT **pointsEnd)
-{
- if(s_qhull_output && s_qhull_output->initialized()){
- *dimension= qh hull_dim;
- *pointsEnd= qh first_point+qh num_points*qh hull_dim;
- return qh first_point;
- }else if(s_has_points){
- *dimension= s_points_dimension;
- *pointsEnd= s_points_end;
- return s_points_begin;
- }
- throw QhullError(10059, "Qhull error: missing definition for currentPoints(). Need currentQhull() or setGlobalDistanceEpsilon()");
-}//currentPoints
-
-Qhull &UsingLibQhull::
-currentQhull()
-{
- if(!s_qhull_output){
- throw QhullError(10055, "Qhull error: currentQhull not defined. Run qhull first.");
- }
- return *s_qhull_output;
-}//currentQhull
-
-// for QhullVertex::dimension() when >= 16
-int UsingLibQhull::
-currentVertexDimension()
-{
- if(s_qhull_output && s_qhull_output->initialized()){
- return s_qhull_output->dimension();
- }else if(s_has_vertex_dimension){
- return s_vertex_dimension;
- }
- throw QhullError(10057, "Qhull error: missing definition for currentVertexDimension(). Need currentQhull() or setGlobalVertexDimension()");
-}//currentVertexDimension
-
-const coordT *UsingLibQhull::
-globalPoints(int *dimension, const coordT **pointsEnd)
-{
- if(s_has_points){
- *dimension= s_points_dimension;
- *pointsEnd= s_points_end;
- return s_points_begin;
- }else{
- return currentPoints(dimension, pointsEnd);
- }
-}//globalPoints
-
-bool UsingLibQhull::
-hasPoints()
-{
- return s_has_points || (s_qhull_output && s_qhull_output->initialized());
-}
-
-bool UsingLibQhull::
-hasVertexDimension()
-{
- return s_has_vertex_dimension || (s_qhull_output && s_qhull_output->initialized());
-}
-
-void UsingLibQhull::
-setGlobals()
-{
- if(s_qhull_output && s_qhull_output->initialized()){
- QhullQh *qqh= s_qhull_output->qhullQh();
- s_angle_epsilon= qqh->ANGLEround*FACTORepsilon;
- s_distance_epsilon= qqh->DISTround*FACTORepsilon;
- s_points_begin= qqh->first_point;
- s_points_dimension= qqh->hull_dim;
- s_points_end= s_points_begin+qqh->num_points*s_points_dimension;
- s_vertex_dimension= qqh->hull_dim;
- s_has_angle_epsilon= true;
- s_has_distance_epsilon= true;
- s_has_points= true;
- s_has_vertex_dimension= true;
- }else{
- throw QhullError(10058, "Qhull error: setGlobals can only be called for currentQhull(). Run qhull first.");
- }
- }//setGlobals
-
-void UsingLibQhull::
-unsetGlobals()
-{
- s_has_angle_epsilon= false;
- s_has_distance_epsilon= false;
- s_has_points= false;
- s_has_vertex_dimension= false;
-}//unsetGlobals
-
-#// Methods
-
-void UsingLibQhull::
-maybeThrowQhullMessage(int exitCode) const
-{
- my_qhull->maybeThrowQhullMessage(exitCode);
- QhullError e= checkRunId(); // Check for qhRunId after libqhull returns. For convenience, ought to be at end of libqhull try block
- if(e.isDefined()){
- throw e;
- }
-}//maybeThrowQhullMessage
-
-void UsingLibQhull::
-maybeThrowQhullMessage(int exitCode, int noThrow) const
-{
- my_qhull->maybeThrowQhullMessage(exitCode, noThrow);
- QhullError e= checkRunId(); // Check for qhRunId after libqhull returns. For convenience, ought to be at end of libqhull try block
- if(e.isDefined()){
- e.logError();
- }
-}//maybeThrowQhullMessage
-
-#//Helpers
-
-//! Return QhullError for maybeThrowFromDestructor()
-QhullError UsingLibQhull::
-checkRunId() const
-{
- // Predeclaring QhullError results in four copy constructors, none used here
-#if qh_QHpointer
- if(qh_qh){ // 0 if ~Qhull
- if(my_qhull->qhull_run_id!=qh run_id){
- return QhullError(10047, "Qhull internal error: Global state (qh_qh, run_id %d) changed. Should be runId %d. Another thread?", qh run_id, my_qhull->qhull_run_id);
- }
- }
-#else
- if(qh run_id!=0 && my_qhull->qhull_run_id!=qh run_id){
- return QhullError(10048, "Qhull internal error: Global state (qh_qh, run_id %d) changed. Should be runId %d. Another thread?", qh run_id, my_qhull->qhull_run_id);
- }
-#endif
- return QhullError();
-}//checkRunId
-
-//! Can not embed UsingLibQhull. Otherwise allocated a C++ object missed by qh_errexit
-void UsingLibQhull::
-checkUsingLibQhull() const
-{
- if(s_using_libqhull){
- if(s_qhull_output){
- throw QhullError(10049, "Qhull error: UsingLibQhull already in use by QhullQh.runId %d", s_qhull_output->qhull_run_id);
- }else{
- throw QhullError(10050, "Qhull error: UsingLibQhull already in use. No s_qhull_output");
- }
- }
- s_using_libqhull= true;
-}//checkUsingLibQhull
-
-}//namespace orgQhull
-
diff --git a/src/libqhullpcpp/UsingLibQhull.h b/src/libqhullpcpp/UsingLibQhull.h
deleted file mode 100644
index 6bf2b49..0000000
--- a/src/libqhullpcpp/UsingLibQhull.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/UsingLibQhull.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef USINGlibqhull_H
-#define USINGlibqhull_H
-
-#include "QhullError.h"
-extern "C" {
-#include "libqhull/libqhull.h"
-}
-
-namespace orgQhull {
-
-#//!\name Types
- //! UsingLibQhull -- Interface into libqhull and its 'qh' and 'qhstat' macros
- //! Always use with setjmp() for libqhull error handling.
-
-/*******************************
-
-UsingLibQhull is stack based, but as a call
-Qhull declarations are stack-based. But can't define a
-setjmp environment, since the target goes away. So must be UsingLibQhull, but can only have one
-setjmp at a time? Can embedded another Using as long as save/restore
-longjmp on exit.
-*/
- class UsingLibQhull;
-
- // Defined elsewhere
- class Qhull;
-
-#//!\name Global variables
-extern Qhull * s_qhull_output; //! Provide qh_fprintf (Qhull.cpp) access to Qhull
-
-class UsingLibQhull {
-
-private:
-#//!\name Fields
- Qhull * my_qhull;
- int qh_exitcode;
-
-#//!\name Class globals
- //! Global flags
- static bool s_using_libqhull; //! True if UsingLibQhull is in scope
-
- //! Use global values if s_has_... is set
- static bool s_has_angle_epsilon; //! True if s_angle_epsilon defined
- static bool s_has_distance_epsilon; //! True if s_distance_epsilon defined
- static bool s_has_points; //! If False (default), Qhull() runs setPointBase()
- static bool s_has_vertex_dimension; //! True if s_vertex_dimension defined
-
- //! Global values
- static double s_angle_epsilon; //! Epsilon for angle equality
- static double s_distance_epsilon; //! Epsilon for distance equality
- static const coordT *s_points_begin; //! For QhullPoint::id() w/o qhRunId.
- static const coordT *s_points_end; //! For QhullPoint::id() w/o qhRunId.
- static int s_points_dimension;
- static int s_vertex_dimension; //! Default dimension (e.g., if Vertex::dimension() >= 16)
-
-public:
-#//!\name Class constants
- static const int NOqhRunId= 0; //! qh_qh is not available
- static const int NOthrow= 1; //! Do not throw from maybeThrowQhullMessage
- static const int FACTORepsilon= 10; //!
- static const double DEFAULTdistanceEpsilon; //! ~DISTround*FACTORepsilon for unit cube
- static const double DEFAULTangleEpsilon; //! ~ANGLEround*FACTORepsilon for unit cube
-
-#//!\name Class members
- static void checkQhullMemoryEmpty();
- static double currentAngleEpsilon();
- static double currentDistanceEpsilon();
- static const coordT *currentPoints(int *dimension, const coordT **pointsEnd);
- static Qhull & currentQhull();
- static int currentVertexDimension();
- static double globalAngleEpsilon() { return s_has_angle_epsilon ? s_angle_epsilon : currentAngleEpsilon(); }
- static double globalDistanceEpsilon() { return s_has_distance_epsilon ? s_distance_epsilon : currentDistanceEpsilon(); }
- static double globalMachineEpsilon() { return REALepsilon; }
- static const coordT *globalPoints(int *dimension, const coordT **pointsEnd);
- static int globalVertexDimension() { return s_has_vertex_dimension ? s_vertex_dimension : currentVertexDimension(); }
- static bool hasPoints(); // inline would require Qhull.h
- static bool hasVertexDimension();
- static void setGlobalAngleEpsilon(double d) { s_angle_epsilon=d; s_has_angle_epsilon= true; }
- static void setGlobalDistanceEpsilon(double d) { s_distance_epsilon= d; s_has_distance_epsilon= true; }
- static void setGlobalPoints(int dimension, const coordT *pointsBegin, const coordT *pointsEnd) { s_points_dimension= dimension; s_points_begin= pointsBegin; s_points_end= pointsEnd; s_has_points= true; }
- static void setGlobalVertexDimension(int i) { s_vertex_dimension= i; s_has_vertex_dimension= true; }
- static void setGlobals();
- static void unsetGlobalAngleEpsilon() { s_has_angle_epsilon= false; }
- static void unsetGlobalDistanceEpsilon() { s_has_distance_epsilon= false; }
- static void unsetGlobalPoints() { s_has_points= false; }
- static void unsetGlobalVertexDimension() { s_has_vertex_dimension= false; }
- static void unsetGlobals();
-
-#//!\name Constructors
- UsingLibQhull(Qhull *p);
- UsingLibQhull(Qhull *p, int noThrow);
- UsingLibQhull(int qhRunId);
- ~UsingLibQhull();
-
-private: //! disable default constructor, copy constructor, and copy assignment
- UsingLibQhull();
- UsingLibQhull(const UsingLibQhull &);
- UsingLibQhull & operator=(const UsingLibQhull &);
-public:
-
-#//!\name Methods
-#//!\name Access
- bool defined() const { return my_qhull!=0; }
- void maybeThrowQhullMessage(int exitCode) const;
- void maybeThrowQhullMessage(int exitCode, int noThrow) const;
-
-#//!\name Helpers
-private:
- QhullError checkRunId() const;
- void checkUsingLibQhull() const;
-
-/***********************************
-You may use global variables in 'qh' after declaring UsingLibQhull. For example
-
- UsingLibQhull q(qhRunId);
- // NOerrors -- no calls that throw libqhull errors
- cout << "Delaunay Mode: " << qh DELAUNAY;
-
-To trap errors from libqhull, UsingLibQhull must be followed by
-
-UsingLibQhull q(qhRunId);
-int exitCode = setjmp(qh errexit);
-if(!exitCode){ // no object creation -- destructors skipped on longjmp()
- calls to libqhull
-}
-q.maybeThrowQhullMessage(exitCode);
-
-The call to setjmp() can not be moved to a method. The stack must be preserved for error exits from libqhull.
-
-*/
-
-};//UsingLibQhull
-
-}//namespace orgQhull
-
-#endif // USINGlibqhull_H
diff --git a/src/libqhullpcpp/functionObjects.h b/src/libqhullpcpp/functionObjects.h
deleted file mode 100644
index 7695467..0000000
--- a/src/libqhullpcpp/functionObjects.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/functionObjects.h#3 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef QHFUNCTIONOBJECTS_H
-#define QHFUNCTIONOBJECTS_H
-
-#include <stdlib.h>
-#include <math.h>
-
-namespace orgQhull {
-#//!\name Type
-
- //! 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/libqhullpcpp/libqhullpcpp.pro b/src/libqhullpcpp/libqhullpcpp.pro
deleted file mode 100644
index ad64c0e..0000000
--- a/src/libqhullpcpp/libqhullpcpp.pro
+++ /dev/null
@@ -1,72 +0,0 @@
-# -------------------------------------------------
-# libqhullpcpp.pro -- Qt project for Qhull cpp shared library based on libqhullp
-# -------------------------------------------------
-
-include(../qhull-warn.pri)
-
-DESTDIR = ../../lib
-TEMPLATE = lib
-CONFIG += staticlib warn_on
-CONFIG -= qt rtti
-build_pass:CONFIG(debug, debug|release):{
- TARGET = qhullcpp_pd
- OBJECTS_DIR = Debug
-}else:build_pass:CONFIG(release, debug|release):{
- TARGET = qhullcpp_p
- OBJECTS_DIR = Release
-}
-MOC_DIR = moc
-
-DEFINES += qh_QHpointer # libqhull/user.h
-
-INCLUDEPATH += ../../src
-INCLUDEPATH += $$PWD # for MOC_DIR
-
-CONFIG += qhull_warn_shadow qhull_warn_conversion
-
-SOURCES += ../libqhullpcpp/Coordinates.cpp
-SOURCES += ../libqhullpcpp/PointCoordinates.cpp
-SOURCES += ../libqhullpcpp/Qhull.cpp
-SOURCES += ../libqhullpcpp/QhullFacet.cpp
-SOURCES += ../libqhullpcpp/QhullFacetList.cpp
-SOURCES += ../libqhullpcpp/QhullFacetSet.cpp
-SOURCES += ../libqhullpcpp/QhullHyperplane.cpp
-SOURCES += ../libqhullpcpp/QhullPoint.cpp
-SOURCES += ../libqhullpcpp/QhullPoints.cpp
-SOURCES += ../libqhullpcpp/QhullPointSet.cpp
-SOURCES += ../libqhullpcpp/QhullQh.cpp
-SOURCES += ../libqhullpcpp/QhullRidge.cpp
-SOURCES += ../libqhullpcpp/QhullSet.cpp
-SOURCES += ../libqhullpcpp/QhullStat.cpp
-SOURCES += ../libqhullpcpp/QhullVertex.cpp
-SOURCES += ../libqhullpcpp/QhullVertexSet.cpp
-SOURCES += ../libqhullpcpp/RboxPoints.cpp
-SOURCES += ../libqhullpcpp/RoadError.cpp
-SOURCES += ../libqhullpcpp/RoadLogEvent.cpp
-SOURCES += ../libqhullpcpp/UsingLibQhull.cpp
-
-HEADERS += ../libqhullpcpp/Coordinates.h
-HEADERS += ../libqhullpcpp/functionObjects.h
-HEADERS += ../libqhullpcpp/PointCoordinates.h
-HEADERS += ../libqhullpcpp/Qhull.h
-HEADERS += ../libqhullpcpp/QhullError.h
-HEADERS += ../libqhullpcpp/QhullFacet.h
-HEADERS += ../libqhullpcpp/QhullFacetList.h
-HEADERS += ../libqhullpcpp/QhullFacetSet.h
-HEADERS += ../libqhullpcpp/QhullHyperplane.h
-HEADERS += ../libqhullpcpp/QhullIterator.h
-HEADERS += ../libqhullpcpp/QhullLinkedList.h
-HEADERS += ../libqhullpcpp/QhullPoint.h
-HEADERS += ../libqhullpcpp/QhullPoints.h
-HEADERS += ../libqhullpcpp/QhullPointSet.h
-HEADERS += ../libqhullpcpp/QhullQh.h
-HEADERS += ../libqhullpcpp/QhullRidge.h
-HEADERS += ../libqhullpcpp/QhullSet.h
-HEADERS += ../libqhullpcpp/QhullSets.h
-HEADERS += ../libqhullpcpp/QhullStat.h
-HEADERS += ../libqhullpcpp/QhullVertex.h
-HEADERS += ../libqhullpcpp/QhullVertexSet.h
-HEADERS += ../libqhullpcpp/RboxPoints.h
-HEADERS += ../libqhullpcpp/RoadError.h
-HEADERS += ../libqhullpcpp/RoadLogEvent.h
-HEADERS += ../libqhullpcpp/UsingLibQhull.h
diff --git a/src/libqhullpcpp/qhull_interface.cpp b/src/libqhullpcpp/qhull_interface.cpp
deleted file mode 100644
index 7c81511..0000000
--- a/src/libqhullpcpp/qhull_interface.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*<html><pre> -<a href="../libqhull/qh-user.htm"
- >-------------------------------</a><a name="TOP">-</a>
-*/
-
-#include <iostream.h>
-#include <conio.h>
-
-//--- Include qhull, so it works from with in a C++ source file
-//---
-//--- In MVC one cannot just do:
-//---
-//--- extern "C"
-//--- {
-//--- #include "qhull_a.h"
-//--- }
-//---
-//--- Because qhull_a.h includes math.h, which can not appear
-//--- inside a extern "C" declaration.
-//---
-//--- Maybe that why Numerical recipes in C avoid this problem, by removing
-//--- standard include headers from its header files and add them in the
-//--- respective source files instead.
-//---
-//--- [K. Erleben]
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <libqhull/qhulllib.h>
-#include <libqhull/mem.h>
-#include <libqhull/qset.h>
-#include <libqhull/geom.h>
-#include <libqhull/merge.h>
-#include <libqhull/poly.h>
-#include <libqhull/io.h>
-#include <libqhull/stat.h>
-#if defined(__cplusplus)
-}
-#endif
-
-/*********************************************************************/
-/* */
-/* */
-/* */
-/* */
-/*********************************************************************/
-
-void compute_convex_hull(void)
-{
- int dim; /* dimension of points */
- int numpoints; /* number of points */
- coordT *points; /* array of coordinates for each point */
- boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
- char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
- FILE *outfile= stdout; /* output from qh_produce_output()
- use NULL to skip qh_produce_output() */
- FILE *errfile= stderr; /* error messages from qhull code */
- int exitcode; /* 0 if no error from qhull */
- facetT *facet; /* set by FORALLfacets */
- int curlong, totlong; /* memory remaining after qh_memfreeshort */
-
- /* initialize dim, numpoints, points[], ismalloc here */
- exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
- flags, outfile, errfile);
- if (!exitcode) { /* if no error */
- /* 'qh facet_list' contains the convex hull */
- FORALLfacets {
- /* ... your code ... */
- }
- }
- qh_freeqhull(!qh_ALL);
- qh_memfreeshort(&curlong, &totlong);
- if (curlong || totlong)
- fprintf(errfile, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
- totlong, curlong);
-};
-
-/*********************************************************************/
-/* */
-/* */
-/* */
-/* */
-/*********************************************************************/
-
-void main()
-{
- cout << "Hello world" << endl;
-
- cout << "Press any key..." << endl;
-
- while (!_kbhit());
-
-};
diff --git a/src/libqhullpcpp/qt-qhull.cpp b/src/libqhullpcpp/qt-qhull.cpp
deleted file mode 100644
index fae481f..0000000
--- a/src/libqhullpcpp/qt-qhull.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/libqhullpcpp/qt-qhull.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include <QList>
-#include "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 {
-
-#//Conversions
-
-QList<coordT> Coordinates::
-toQList() const
-{
- CoordinatesIterator i(*this);
- QList<coordT> cs;
- while(i.hasNext()){
- cs.append(i.next());
- }
- return cs;
-}//toQList
-
-QList<QhullFacet> QhullFacetList::
-toQList() const
-{
- QhullLinkedListIterator<QhullFacet> i(*this);
- QList<QhullFacet> vs;
- while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.append(f);
- }
- }
- return vs;
-}//toQList
-
-//! Same as PrintVertices
-QList<QhullVertex> QhullFacetList::
-vertices_toQList(int qhRunId) const
-{
- QList<QhullVertex> vs;
- QhullVertexSet qvs(qhRunId, first().getFacetT(), NULL, isSelectAll());
- for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
- vs.push_back(*i);
- }
- return vs;
-}//vertices_toQList
-
-QList<QhullFacet> QhullFacetSet::
-toQList() const
-{
- QhullSetIterator<QhullFacet> i(*this);
- QList<QhullFacet> vs;
- while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.append(f);
- }
- }
- return vs;
-}//toQList
-
-#ifdef QHULL_USES_QT
-QList<coordT> QhullHyperplane::
-toQList() const
-{
- QhullHyperplaneIterator i(*this);
- QList<coordT> fs;
- while(i.hasNext()){
- fs.append(i.next());
- }
- fs.append(hyperplane_offset);
- return fs;
-}//toQList
-#endif //QHULL_USES_QT
-
-QList<coordT> QhullPoint::
-toQList() const
-{
- QhullPointIterator i(*this);
- QList<coordT> vs;
- while(i.hasNext()){
- vs.append(i.next());
- }
- return vs;
-}//toQList
-
-QList<QhullPoint> QhullPoints::
-toQList() const
-{
- QhullPointsIterator i(*this);
- QList<QhullPoint> vs;
- while(i.hasNext()){
- vs.append(i.next());
- }
- return vs;
-}//toQList
-
-QList<QhullPoint> QhullPointSet::
-toQList() const
-{
- QhullPointSetIterator i(*this);
- QList<QhullPoint> vs;
- while(i.hasNext()){
- vs.append(i.next());
- }
- return vs;
-}//toQList
-
-}//orgQhull
-
diff --git a/src/libqhullr/Makefile b/src/libqhullr/Makefile
deleted file mode 100644
index 7b75649..0000000
--- a/src/libqhullr/Makefile
+++ /dev/null
@@ -1,186 +0,0 @@
-# Simple gcc Makefile for qhull and rbox (default gcc/g++)
-#
-# see README.txt
-#
-# Results
-# qhull Computes convex hulls and related structures
-# qconvex, qdelaunay, qhalf, qvoronoi
-# Specializations of qhull for each geometric structure
-# user_eg An example of using shared library qhull6_p (with qh_QHpointer)
-# user_eg2 An example of using shared library qhull (without qh_QHpointer)
-# testqset Standalone test of qset.c with mem.c
-# libqhullstatic.a Static library for qhull
-#
-# Make targets
-# make Produce all of the results
-# make qhull_all Produce qconvex, etc.
-# Links program sources into src/libqhull
-# make qtest Quick test of qset, rbox, and qhull
-# make doc Print documentation
-# 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 clean Remove object files
-# make cleanall Remove generated files
-#
-# BINDIR directory where to copy executables
-# DESTDIR destination directory
-# 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.a
-#
-# Do not replace tabs with spaces. Needed by 'make' for build rules
-
-# You may build the qhull programs without using a library
-# make qhullx
-
-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, -O2 for optimization, -g for debugging
-CC = gcc
-CC_OPTS1 = -O2 -fPIC -ansi $(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
-
-# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
-#CC = cc
-#CC_OPTS1 = -ansi -O2
-
-# for Next cc compiler with fat executable
-#CC = cc
-#CC_OPTS1 = -ansi -O2 -arch m68k -arch i386 -arch hppa
-
-# For loader, ld,
-CC_OPTS2 = $(CC_OPTS1)
-CXX_OPTS2 = $(CXX_OPTS1)
-
-# Default targets for make
-
-all: qhull_links qhull_all qtest
-
-clean:
- rm -f *.o
- # Delete linked files from other directories [qhull_links]
- rm -f qconvex.c unix.c qdelaun.c qhalf.c qvoronoi.c rbox.c
- rm -f user_eg.c user_eg2.c testqset.c
-
-cleanall: clean
- rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
- rm -f core user_eg user_eg2 testqset libqhullstatic.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.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
-
-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.o stat.o geom2.o poly2.o merge.o \
- libqhull.o geom.o poly.o qset.o mem.o random.o
-
-LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem.o userprintf.o io.o user.o
-
-LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib.o userprintf_rbox.o
-
-LIBQHULL_HDRS= user.h libqhull.h qhull_a.h geom.h \
- io.h mem.h merge.h poly.h random.h \
- qset.h stat.h
-
-# CFILES ordered alphabetically after libqhull.c
-CFILES= ../qhull/unix.c libqhull.c geom.c geom2.c global.c io.c \
- mem.c merge.c poly.c poly2.c random.c rboxlib.c \
- qset.c stat.c user.c usermem.c userprintf.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:
- [ -f qconvex.c ] || ln -s ../qconvex/qconvex.c
- [ -f qdelaun.c ] || ln -s ../qdelaunay/qdelaun.c
- [ -f qhalf.c ] || ln -s ../qhalf/qhalf.c
- [ -f qvoronoi.c ] || ln -s ../qvoronoi/qvoronoi.c
- [ -f qhull.c ] || ln -s ../qhull/unix.c
- [ -f rbox.c ] || ln -s ../rbox/rbox.c
- [ -f user_eg.c ] || ln -s ../user_eg/user_eg.c
- [ -f user_eg2.c ] || ln -s ../user_eg2/user_eg2.c
- [ -f testqset.c ] || ln -s ../testqset/testqset.c
-
-# compile qhull without using bin/libqhullstatic.a
-qhull_all: qconvex.o qdelaun.o qhalf.o qvoronoi.o unix.o user_eg.o user_eg2.o rbox.o testqset.o $(LIBQHULLS_OBJS)
- $(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex.o
- $(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun.o
- $(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf.o
- $(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi.o
- $(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix.o
- $(CC) -o rbox $(CC_OPTS2) -lm rbox.o rboxlib.o random.o usermem.o userprintf_rbox.o
- $(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg.o
- $(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2.o usermem.o userprintf.o io.o
- $(CC) -o testqset $(CC_OPTS2) -lm mem.o qset.o testqset.o
- -ar -rs libqhullstatic.a $(LIBQHULLS_OBJS)
- #libqhullstatic.a is not needed for qhull
- #If 'ar -rs' fails try using 'ar -s' with 'ranlib'
- #ranlib libqhullstatic.a
-
-qtest:
- @echo Testing qset.c and mem.c with testqset
- ./testqset 10000
- @echo Run the qhull smoketest
- ./rbox D4 | ./qhull
-
-# end of Makefile
diff --git a/src/libqhullr/README_r.txt b/src/libqhullr/README_r.txt
deleted file mode 100644
index 4c0a7b6..0000000
--- a/src/libqhullr/README_r.txt
+++ /dev/null
@@ -1,311 +0,0 @@
-Converting libqhull to libqhullr
-
-==========================
-Todo
-
-After qmake, need to update HEADER paths for libqhull, libqhullr, libqhullcpp libqhullpcpp
- Path="..\lib
- Path="..\..\src\lib
-
-countT everywhere, problem of strings
-
-Questions
- Can construct pointSets, add a mid() function?
- Does C++ auto create default iterator if another constructor already exists?
- Change other to o?
-
-OK
- QhullQh
- Coordinates
- QhullPoint!
-
-
-
-create countT for int64 IDs
-change vertexId for 'int'
-
-Get rid of static
- user.c qh_new_qhull
- static boolT firstcall = True;
-
- UsingLibQhull
- lots
-
- QhullQh
- static boolT firstcall = True;
-
-
----
-Convert qhulltest.cpp to libqhullcpp and branch old code
-At initialization, check for compatible libqhull. Add a version check to libqhull
-
-Convert testqset.c to testqset_r.c
- Try to make qhT and mem_r.c etc. plugable
-Convert user_eg to qhull_r.dll
-Convert user_eg2 to libqhullstatic_r.a
-Convert user_eg3 to libqhullcpp
-Rework user_eg7.cpp,etc for new names, add to README
-
-
----
-3>..\..\src\qhullr\unix_r.c(39) : warning C4273: '_isatty' : inconsistent dll linkage
-3> C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\io.h(209) : see previous definition of '_isatty'
-
----
-Redo usage note for qhullr.cpp
-
----
-/*** uncomment here and qhull_a.h
- if string.h does not define memcpy()
-#include <memory.h>
-*/
-
----
-Run through valgrind
-
----
-Fix or "sample code" in user_r.h
-
-and in user_r.c
- qh_call_qhull(qh, void )
- template for calling qhull from inside your program
-
---
-Try with and without qh_NOmem
-
---
-Update
- README.txt -- the new subprojects
- CMakeLists.txt
-
-==============
-Steps to update C code to reentrant qhull (e.g., testqset_r.c, user_eg*.c)
-
-Branch the code to ..._r.c
-
-Rename include files
-#include "qhull_ar.h"
-
-Allocate qh at the top, and remove other references to qh_qh and qh_qhPOINTER
- qhT qh_qh;
- qhT *qh= &qh_qh;
-
-If needed, remove spaces between name and argument list
- {[^a-zA-Z0-9_][a-zA-Z0-9_]*} \(
- \1(
-
-Make the following regexp substitions [DevStudio use {} for grouping instead of ()]
-
- Prefix function declarations with "(qhT *qh, "
- ^{[a-zA-Z0-9]* [a-zA-Z0-9]*\}(
- \1(qhT *qh,
-
- 'qh' is the first argument for most internal calls and qhull calls
- \({[a-zA-Z0-9_]*, }
- (qh, \1
-
- \({[a-zA-Z0-9_]+}\)
- (qh, \1)
-
- \(\)
- (qh)
-
- 'qh '
- 'qh->'
-
-Other substitions to consider
-
- ("
- (qh, "
-
- (&
- (qh, &
-
- ()
- (qh)
-
-Review the code for obvious errors
-Remove qhT for functions that do not need it
-
-Make the following substitions to correct mistakes made above
- qh, qh,
- qh,
-
- qh, void
- qh
-Review the code for routines that do not take qh
-
-Compile and fix the errors
-
-==============
-Steps
-
-Build qhullr.sln from qhull_all.sln
- Shadow build isn't working for header files. libbqhull and libqhullr
- RelativePath="..\..\src\libqhull\
- Doesn't create qhullstatic_rd.lib
- Inconsistent dll linkage for _isatty
-
- include only libqhullstaticr and qhullr
- remove libqhull, libqhullp, libqhullr to avoid double searches
- remove all but testqset from testqset
-
-Replace all include files with _r.h
-
-[qhull_all] Remove all spaces before the parens 'qh_... (...)'
-[qhull_all] Change copyright to 2014
-
-Checked in source
-
-Check for access to .c and .h files
-
-Add qhmemT *qh before all routines
- # Routines with arguments, 3648+498 occurrences
- {qh_[a-zA-Z0-9_]*[^_]\(}{[^)/]}
- \1qhmemT *qh, \2
-
- # Routines with comment args, 15+ occurrences
- {qh_[a-zA-Z0-9_]*[^_]\(}{[/]}
- \1qhmemT *qh \2
-
-Exceptions 104+55 instances
- qhmemT *qh, void
- qhmemT *qh
-
- # times
- SETtruncate_(qhmemT *qh,
- _(
-
- qhmemT *qh, qhmemT *qh,
- qhmemT *qh,
-
- qhmemT *qh, qhmemT *qh
- qhmemT *qh
-
-In C code
- ^{ *qh_.*}qhmemT *qh
- \1qh
-
- # 602 occurrences, needs repeat
- ^{ .*}qhmemT *qh
- \1qh
-
- # 3746 occurrences
- {[^a-z]}qh {[a-zA-Z]}
- \1qh->\2
-
-All files, 891 occurrences
- qhmemT \*qh{[^a-zA-Z]}
- qhT *qh\1
-
- qhT *qh *
- qhT *qh, void *
-
- qhmem.
- qh->qhmem.
-
- # 99 occurrences
- qhstat
- qh->qhstat.
-
-Removed rboxT from rboxlib_r.c
-
-1138 errors and 438 warnings.
-
-Remove dependency on libqhull_r for statT
-Convert FOREACHsetelement_i_ in libqhull_r.h
-traceN needs qh for qh_fprintf
-add qh to () calls
-
-Down to 600 errors
-
-Thurs at 7:18p after fixing all of the compile errors and removing qh_qhPOINTER
-
-# Debug version of qhullr
- 59 files changed, 8849 insertions(+), 8900 deletions(-)
-
-ISPY-/local/qhull/bin> rbox 100000 t100 s | qhullr
-
-Convex hull of 100000 points in 3-d:
-
- Number of vertices: 100000
- Number of facets: 199996
-
-Statistics for: rbox 100000 t100 s | qhullr
-
- Number of points processed: 100000
- Number of hyperplanes created: 565761
- Number of distance tests for qhull: 4376829
- CPU seconds to compute hull (after input): 1.688
-
-# Release version 2012.1
-
-ISPY-/local/qhull/bin> rbox 100000 t100 s | qhull
-
-Convex hull of 100000 points in 3-d:
-
- Number of vertices: 100000
- Number of facets: 199996
-
-Statistics for: rbox 100000 t100 s | qhull
-
- Number of points processed: 100000
- Number of hyperplanes created: 565761
- Number of distance tests for qhull: 4376829
- CPU seconds to compute hull (after input): 1
-
-# Release version of rboxr and qhullr
-
-ISPY-/local/qhull/bin> rboxr 100000 t100 s | qhullr
-
-Convex hull of 100000 points in 3-d:
-
- Number of vertices: 100000
- Number of facets: 199996
-
-Statistics for: rboxr 100000 t100 s | qhullr
-
- Number of points processed: 100000
- Number of hyperplanes created: 565761
- Number of distance tests for qhull: 4376829
- CPU seconds to compute hull (after input): 1
-
------
-Reorganized projects for cpp.
-
-Fixed up qhull_p-exports.def. qhull_r-exports.def has no DATA records.
-
-user_eg3 with libqhullpcpp worked correctly the first time
-
-IISPY-/local/qhull/bin> user_eg3 rbox "100000 t100 s" qhull
-rbox 100000 t100 s
-
-Results of qhull
-
-Convex hull of 100000 points in 3-d:
-
- Number of vertices: 100000
- Number of facets: 199996
-
-Statistics for: rbox "100000 t100 s" | qhull
-
- Number of points processed: 100000
- Number of hyperplanes created: 565761
- Number of distance tests for qhull: 4376829
- CPU seconds to compute hull (after input): 1.672
-
----------------------
-Fix cpp formating with */& associated with type and ~ at column 25
-
- \~
- ~
-
-{ *} &
- &\1
-
-{ *} \*\*
- **\1
-
-On *.h only in cpp files
-{ *} \*
- *\1
diff --git a/src/libqhullr/libqhullr.pro b/src/libqhullr/libqhullr.pro
deleted file mode 100644
index b70327e..0000000
--- a/src/libqhullr/libqhullr.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-# -------------------------------------------------
-# libqhullr.pro -- Qt project for Qhull shared library
-# Built with qh_QHpointer=1
-# -------------------------------------------------
-
-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/libqhullr/qhull_r-exports.def
-
-include(../qhull-libqhull-src_r.pri)
diff --git a/src/libqhullr/qh-geom.htm b/src/libqhullr/qh-geom.htm
deleted file mode 100644
index 2e7c5e0..0000000
--- a/src/libqhullr/qh-geom.htm
+++ /dev/null
@@ -1,293 +0,0 @@
-<!-- Do not edit with Front Page, it adds too many spaces -->
-<html>
-<head>
-<meta http-equiv="Content-Type"
-content="text/html; charset=iso-8859-1">
-<title>geom.c, geom2.c -- geometric and floating point routines</title>
-</head>
-
-<body>
-<!-- Navigation links -->
-<p><a name="TOP"><b>Up:</b></a> <a
-href="http://www.qhull.org">Home page</a> for Qhull<br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm#TOC">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
-</p>
-
-<hr>
-<!-- Main text of document. -->
-
-<h2>geom.c, geom2.c, random.c -- geometric and floating point routines</h2>
-<blockquote>
-<p>Geometrically, a vertex is a point with <em>d</em> coordinates
-and a facet is a halfspace. A <em>halfspace</em> is defined by an
-oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
-is defined by <em>d</em> normalized coefficients and an offset. A
-point is <em>above</em> a facet if its distance to the facet is
-positive.</p>
-
-<p>Qhull uses floating point coordinates for input points,
-vertices, halfspace equations, centrums, and an interior point.</p>
-
-<p>Qhull may be configured for single precision or double
-precision floating point arithmetic (see <a href="user.h#realT">realT</a>
-). </p>
-
-<p>Each floating point operation may incur round-off error (see
-<a href="qh-merge.htm#TOC">Merge</a>). 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. </p>
-</blockquote>
-<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
-<hr>
-<p><a href="#TOP">&#187;</a> <b>Geom</b>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
-<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
-<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
-<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
-<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
-
-<h3>Index to <a href="geom.c">geom.c</a>,
-<a href="geom2.c">geom2.c</a>, <a href="geom.h">geom.h</a>,
-<a href="random.c">random.c</a>, <a href="random.h">random.h</a>
-</h3>
-
-<ul>
-<li><a href="#gtype">geometric data types and constants</a> </li>
-<li><a href="#gmacro">mathematical macros</a>
-</li>
-<li><a href="#gmath">mathematical functions</a> </li>
-<li><a href="#gcomp">computational geometry functions</a> </li>
-<li><a href="#gpoint">point array functions</a> </li>
-<li><a href="#gfacet">geometric facet functions</a> </li>
-<li><a href="#ground">geometric roundoff functions</a></li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gtype">geometric data types
-and constants</a></h3>
-
-<ul>
-<li><a href="libqhull.h#coordT">coordT</a> coordinates and
-coefficients are stored as realT</li>
-<li><a href="libqhull.h#pointT">pointT</a> a point is an array
-of <tt>DIM3</tt> coordinates </li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gmacro">mathematical macros</a></h3>
-
-<ul>
-<li><a href="geom.h#fabs_">fabs_</a> returns the absolute
-value of a </li>
-<li><a href="geom.h#fmax_">fmax_</a> returns the maximum
-value of a and b </li>
-<li><a href="geom.h#fmin_">fmin_</a> returns the minimum
-value of a and b </li>
-<li><a href="geom.h#maximize_">maximize_</a> maximize a value
-</li>
-<li><a href="geom.h#minimize_">minimize_</a> minimize a value
-</li>
-<li><a href="geom.h#det2_">det2_</a> compute a 2-d
-determinate </li>
-<li><a href="geom.h#det3_">det3_</a> compute a 3-d
-determinate </li>
-<li><a href="geom.h#dX">dX, dY, dZ</a> compute the difference
-between two coordinates </li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gmath">mathematical functions</a></h3>
-
-<ul>
-<li><a href="geom.c#backnormal">qh_backnormal</a> solve for
-normal using back substitution </li>
-<li><a href="geom2.c#crossproduct">qh_crossproduct</a>
-compute the cross product of two 3-d vectors </li>
-<li><a href="geom2.c#determinant">qh_determinant</a> compute
-the determinant of a square matrix </li>
-<li><a href="geom.c#gausselim">qh_gausselim</a> Gaussian
-elimination with partial pivoting </li>
-<li><a href="geom2.c#gram_schmidt">qh_gram_schmidt</a>
-implements Gram-Schmidt orthogonalization by rows </li>
-<li><a href="geom2.c#maxabsval">qh_maxabsval</a> return max
-absolute value of a vector </li>
-<li><a href="geom2.c#minabsval">qh_minabsval</a> return min
-absolute value of a dim vector </li>
-<li><a href="geom2.c#mindiff">qh_mindiff</a> return index of
-min absolute difference of two vectors </li>
-<li><a href="geom.c#normalize">qh_normalize</a> normalize a
-vector </li>
-<li><a href="geom.c#normalize2">qh_normalize2</a> normalize a
-vector and report if too small </li>
-<li><a href="geom2.c#printmatrix">qh_printmatrix</a> print
-matrix given by row vectors </li>
-<li><a href="random.c#rand">qh_rand/srand</a> generate random
-numbers </li>
-<li><a href="random.c#randomfactor">qh_randomfactor</a> return
-a random factor near 1.0 </li>
-<li><a href="random.c#randommatrix">qh_randommatrix</a>
-generate a random dimXdim matrix in range (-1,1) </li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gcomp">computational geometry functions</a></h3>
-
-<ul>
-<li><a href="geom2.c#detsimplex">qh_detsimplex</a> compute
-determinate of a simplex of points </li>
-<li><a href="io.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
-<li><a href="geom2.c#distnorm">qh_distnorm</a> compute
-distance from point to hyperplane as defined by normal and offset</li>
-<li><a href="geom2.c#facetarea_simplex">qh_facetarea_simplex</a>
-return area of a simplex</li>
-<li><a href="geom.c#getangle">qh_getangle</a> return cosine
-of angle (i.e., dot product) </li>
-<li><a href="geom.c#getcenter">qh_getcenter</a> return
-arithmetic center for a set of vertices </li>
-<li><a href="geom2.c#pointdist">qh_pointdist</a> return
-distance between two points </li>
-<li><a href="geom2.c#rotatepoints">qh_rotatepoints</a> rotate
-numpoints points by a row matrix </li>
-<li><a href="geom2.c#sethalfspace">qh_sethalfspace</a> set
-coords to dual of halfspace relative to an interior point </li>
-<li><a href="geom.c#sethyperplane_det">qh_sethyperplane_det</a>
-return hyperplane for oriented simplex using determinates
-</li>
-<li><a href="geom.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
-return hyperplane for oriented simplex using Gaussian
-elimination </li>
-<li><a href="geom2.c#voronoi_center">qh_voronoi_center</a>
-return Voronoi center for a set of points </li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gpoint">point array functions</a></h3>
-<ul>
-<li><a href="geom2.c#copypoints">qh_copypoints</a> return
-malloc'd copy of points</li>
-<li><a href="geom2.c#joggleinput">qh_joggleinput</a> joggle
-input points by qh.JOGGLEmax </li>
-<li><a href="geom2.c#maxmin">qh_maxmin</a> return max/min
-points for each dimension</li>
-<li><a href="geom2.c#maxsimplex">qh_maxsimplex</a> determines
-maximum simplex for a set of points </li>
-<li><a href="geom2.c#printpoints">qh_printpoints</a> print ids for a
-set of points </li>
-<li><a href="geom2.c#projectinput">qh_projectinput</a> project
-input using qh DELAUNAY and qh low_bound/high_bound </li>
-<li><a href="geom2.c#projectpoints">qh_projectpoints</a>
-project points along one or more dimensions </li>
-<li><a href="geom2.c#rotateinput">qh_rotateinput</a> rotate
-input points using row matrix </li>
-<li><a href="geom2.c#scaleinput">qh_scaleinput</a> scale
-input points using qh low_bound/high_bound </li>
-<li><a href="geom2.c#scalelast">qh_scalelast</a> scale last
-coordinate to [0,m] for Delaunay triangulations </li>
-<li><a href="geom2.c#scalepoints">qh_scalepoints</a> scale
-points to new lowbound and highbound </li>
-<li><a href="geom2.c#setdelaunay">qh_setdelaunay</a> project
-points to paraboloid for Delaunay triangulation </li>
-<li><a href="geom2.c#sethalfspace_all">qh_sethalfspace_all</a>
-generate dual for halfspace intersection with interior
-point </li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gfacet">geometric facet functions</a></h3>
-<ul>
-<li><a href="geom.c#distplane">qh_distplane</a> return
-distance from point to facet </li>
-<li><a href="geom2.c#facetarea">qh_facetarea</a> return area
-of a facet </li>
-<li><a href="geom2.c#facetcenter">qh_facetcenter</a> return
-Voronoi center for a facet's vertices </li>
-<li><a href="geom.c#findbest">qh_findbest</a> find visible
-facet or best facet for a point </li>
-<li><a href="geom.c#findbesthorizon">qh_findbesthorizon</a>
-update best new facet with horizon facets</li>
-<li><a href="geom.c#findbestnew">qh_findbestnew</a> find best
-new facet for point </li>
-<li><a href="geom2.c#getarea">qh_getarea</a> get area of all
-facets in facetlist, collect statistics </li>
-<li><a href="geom.c#getcentrum">qh_getcentrum</a> return
-centrum for a facet </li>
-<li><a href="geom.c#getdistance">qh_getdistance</a> returns
-the max and min distance of a facet's vertices to a
-neighboring facet</li>
-<li><a href="geom2.c#findgooddist">qh_findgooddist</a> find
-best good facet visible for point from facet </li>
-<li><a href="geom2.c#inthresholds">qh_inthresholds</a> return
-True if facet normal within 'Pdn' and 'PDn'</li>
-<li><a href="geom2.c#orientoutside">qh_orientoutside</a>
-orient facet so that <tt>qh.interior_point</tt> is inside</li>
-<li><a href="geom.c#projectpoint">qh_projectpoint</a> project
-point onto a facet </li>
-<li><a href="geom.c#setfacetplane">qh_setfacetplane</a> sets
-the hyperplane for a facet </li>
-<li><a href="geom2.c#sharpnewfacets">qh_sharpnewfacets</a> true
-if new facets contains a sharp corner</li>
-</ul>
-
-<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="ground">geometric roundoff functions</a></h3>
-<ul>
-<li><a href="geom2.c#detjoggle">qh_detjoggle</a> determine
-default joggle for points and distance roundoff error</li>
-<li><a href="geom2.c#detroundoff">qh_detroundoff</a>
-determine maximum roundoff error and other precision constants</li>
-<li><a href="geom2.c#distround">qh_distround</a> compute
-maximum roundoff error due to a distance computation to a
-normalized hyperplane</li>
-<li><a href="geom2.c#divzero">qh_divzero</a> divide by a
-number that is nearly zero </li>
-<li><a href="geom2.c#maxouter">qh_maxouter</a> return maximum outer
-plane</li>
-<li><a href="geom2.c#outerinner">qh_outerinner</a> return actual
-outer and inner planes
-</ul>
-
-<p><!-- Navigation links --> </p>
-<hr>
-<p><b>Up:</b>
-<a href="http://www.qhull.org">Home page for
-Qhull</a> <br>
-<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a> <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
-
-
-<p><!-- GC common information --> </p>
-<hr>
-<p><a href="http://www.geom.uiuc.edu/"><img
-src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
-Geometry Center Home Page </i></p>
-<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
-</a><br>
-Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
-</body>
-</html>
diff --git a/src/libqhullr/qh-io.htm b/src/libqhullr/qh-io.htm
deleted file mode 100644
index 0342809..0000000
--- a/src/libqhullr/qh-io.htm
+++ /dev/null
@@ -1,303 +0,0 @@
-<!-- Do not edit with Front Page, it adds too many spaces -->
-<html>
-<head>
-<meta http-equiv="Content-Type"
-content="text/html; charset=iso-8859-1">
-<title>io.c -- input and output operations</title>
-</head>
-
-<body>
-<!-- Navigation links -->
-<p><a name="TOP"><b>Up:</b></a> <a
-href="http://www.qhull.org">Home page</a> for Qhull<br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
-</p>
-<hr>
-
-<h2>io.c -- input and output operations</h2>
-<blockquote>
-
-<p>Qhull provides a wide range of input
-and output options. To organize the code, most output formats use
-the same driver: </p>
-
-<pre>
- 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 );
-</pre>
-
-<p>Note the 'printall' flag. It selects whether or not
-qh_skipfacet() is tested. </p>
-
-</blockquote>
-<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
-<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">&#149;</a>
-<a href="qh-globa.htm#TOC">Global</a> &#149; <b>Io</b> &#149;
-<a href="qh-mem.htm#TOC">Mem</a> &#149; <a href="qh-merge.htm#TOC">Merge</a> &#149;
-<a href="qh-poly.htm#TOC">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149;
-<a href="qh-set.htm#TOC">Set</a> &#149; <a href="qh-stat.htm#TOC">Stat</a> &#149;
-<a href="qh-user.htm#TOC">User</a> </p>
-
-<h3>Index to <a href="io.c">io.c</a> and <a href="io.h">io.h</a></h3>
-
-<ul>
-<li><a href="#iconst">io.h constants and types</a> </li>
-<li><a href="#ilevel">User level functions</a> </li>
-<li><a href="#iprint">Print functions for all output formats</a></li>
-<li><a href="#itext">Text output functions</a> </li>
-<li><a href="#iutil">Text utility functions</a></li>
-<li><a href="#igeom">Geomview output functions</a> </li>
-<li><a href="#iview">Geomview utility functions</a></li>
-</ul>
-
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iconst">io.h constants and types</a></h3>
-
-<ul>
-<li><a href="io.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
-of first two lines of stdin </li>
-<li><a href="io.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
-values of white space </li>
-<li><a href="io.h#printvridgeT">printvridgeT</a> function to
-print results of qh_printvdiagram or qh_eachvoronoi</li>
-</ul>
-
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="ilevel">User level functions</a></h3>
-
-<ul>
-<li><a href="io.c#copyfilename">qh_copyfilename</a>
-copy filename identified by qh_skipfilename
-<li><a href="io.c#eachvoronoi_all">qh_eachvoronoi_all</a>
-visit each Voronoi ridge of the Voronoi diagram
-<li><a href="io.c#prepare_output">qh_prepare_output</a>
-prepare Qhull for output (called by qh_produce_output())
-<li><a href="io.c#printhelp_degenerate">qh_printhelp_degenerate</a>
-prints descriptive message for precision error </li>
-<li><a href="io.c#printhelp_singular">qh_printhelp_singular</a>
-print help message for singular data </li>
-<li><a href="libqhull.c#printsummary">qh_printsummary</a> print
-summary ('s')</li>
-<li><a href="io.c#produce_output">qh_produce_output</a>
-prints out the result of qhull()</li>
-<li><a href="io.c#produce_output">qh_produce_output2</a>
-prints out the result of qhull() without calling qh_prepare_output()</li>
-<li><a href="io.c#readfeasible">qh_readfeasible</a> read
-interior point from remainder and qh fin ('H')</li>
-<li><a href="io.c#readpoints">qh_readpoints</a> read input
-points </li>
-<li><a href="io.c#setfeasible">qh_setfeasible</a> set
-interior point from qh feasible_string ('Hn,n,n')</li>
-<li><a href="io.c#skipfilename">qh_skipfilename</a>
-skip filename in string
-</ul>
-
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iprint">Print functions for all
-output formats</a></h3>
-
-<ul>
-<li><a href="io.c#countfacets">qh_countfacets</a> count good
-facets for printing and set visitid </li>
-<li><a href="io.c#markkeep">qh_markkeep</a> mark good facets
-that meet qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
-<li><a href="io.c#order_vertexneighbors">qh_order_vertexneighbors</a>
-order neighbors for a 3-d vertex by adjacency ('i', 'o')</li>
-<li><a href="io.c#printafacet">qh_printafacet</a> print facet
-in an output format </li>
-<li><a href="io.c#printbegin">qh_printbegin</a> print header
-for an output format </li>
-<li><a href="io.c#printend">qh_printend</a> print trailer for
-an output format </li>
-<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
-print facets in a facetlist</li>
-<li><a href="io.c#printfacets">qh_printfacets</a> print
-facetlist and/or facet set in an output format </li>
-<li><a href="io.c#printneighborhood">qh_printneighborhood</a>
-print neighborhood of one or two facets ('Po')</li>
-<li><a href="io.c#produce_output">qh_produce_output</a>
-print the results of qh_qhull() </li>
-<li><a href="io.c#skipfacet">qh_skipfacet</a> True if not
-printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
-<li><a href="io.c#facetvertices">qh_facetvertices</a> return
-vertices in a set of facets ('p')</li>
-</ul>
-
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="itext">Text output functions</a></h3>
-<ul>
-<li><a href="io.c#eachvoronoi">qh_eachvoronoi</a>
-print or visit each Voronoi ridge for an input site of the Voronoi diagram
-<li><a href="io.c#printextremes">qh_printextremes</a> print
-extreme points by point ID (vertices of convex hull) ('Fx')</li>
-<li><a href="io.c#printextremes_2d">qh_printextremes_2d</a> print
-2-d extreme points by point ID ('Fx')</li>
-<li><a href="io.c#printextremes_d">qh_printextremes_d</a> print
-extreme points of input sites for Delaunay triangulations ('Fx')</li>
-<li><a href="io.c#printfacet">qh_printfacet</a> print all
-fields of a facet ('f')</li>
-<li><a href="io.c#printfacet2math">qh_printfacet2math</a> print
-2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
-<li><a href="io.c#printfacet3math">qh_printfacet3math</a>
-print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
-<li><a href="io.c#printfacet3vertex">qh_printfacet3vertex</a>
-print vertices for a 3-d facet ('i', 'o')</li>
-<li><a href="io.c#printfacetheader">qh_printfacetheader</a>
-prints header fields of a facet ('f')</li>
-<li><a href="io.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
-print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
-<li><a href="io.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
-print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
-<li><a href="io.c#printfacetridges">qh_printfacetridges</a>
-prints ridges of a facet ('f')</li>
-<li><a href="io.c#printpoints_out">qh_printpoints_out</a> prints
-vertices for facets by their point coordinates ('p')</li>
-<li><a href="io.c#printridge">qh_printridge</a> print all
-fields for a ridge ('f')</li>
-<li><a href="io.c#printvdiagram">qh_printvdiagram</a> print
-voronoi diagram as Voronoi vertices for each input pair</li>
-<li><a href="io.c#printvertex">qh_printvertex</a> print all
-fields for a vertex ('f')</li>
-<li><a href="io.c#printvertexlist">qh_printvertexlist</a>
-print vertices used by a list or set of facets ('f')</li>
-<li><a href="io.c#printvertices">qh_printvertices</a> print a
-set of vertices ('f')</li>
-<li><a href="io.c#printvneighbors">qh_printvneighbors</a>
-print vertex neighbors of vertices ('FN')</li>
-<li><a href="io.c#printvoronoi">qh_printvoronoi</a> print
-voronoi diagram in 'o' or 'G' format</li>
-</ul>
-
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iutil">Text utility functions</a></h3>
-<ul>
-<li><a href="io.c#dfacet">dfacet</a> print facet by ID </li>
-<li><a href="io.c#dvertex">dvertex</a> print vertex by ID </li>
-<li><a href="io.c#compare_facetarea">qh_compare_facetarea</a>
-used by qsort() to order facets by area </li>
-<li><a href="io.c#compare_facetmerge">qh_compare_facetmerge</a>
-used by qsort() to order facets by number of merges </li>
-<li><a href="io.c#compare_facetvisit">qh_compare_facetvisit</a>
-used by qsort() to order facets by visit ID or ID </li>
-<li><a href="io.c#compare_vertexpoint">qh_compare_vertexpoint</a>
-used by qsort() to order vertices by point ID </li>
-<li><a href="io.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
-<li><a href="io.c#detvridge">qh_detvridge</a> determine Voronoi
-ridge for an input site
-<li><a href="io.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
-ridge for an input site
-<li><a href="io.c#facet2point">qh_facet2point</a> return two
-projected temporary vertices for a 2-d facet ('m', 'G')</li>
-<li><a href="io.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
-vertices for printing
-<li><a href="io.c#printcenter">qh_printcenter</a> print
-facet-&gt;center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
-<li><a href="io.c#printpoint">qh_printpoint</a>, qh_printpointid, print
-coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
-<li><a href="io.c#printpoint3">qh_printpoint3</a> prints 2-d,
-3-d, or 4-d point as 3-d coordinates ('G')</li>
-<li><a href="io.c#printvdiagram2">qh_printvdiagram2</a> print
-voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
-<li><a href="io.c#printvnorm">qh_printvnorm</a> print
-separating plane of the Voronoi diagram for a pair of input sites</li>
-<li><a href="io.c#printvridge">qh_printvridge</a> print
-ridge of the Voronoi diagram for a pair of input sites</li>
-<li><a href="io.c#projectdim3">qh_projectdim3</a> project 2-d
-3-d or 4-d point to a 3-d point ('G')</li>
-</ul>
-
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="igeom">Geomview output functions</a></h3>
-<ul>
-<li><a href="io.c#printfacet2geom">qh_printfacet2geom</a>
-print facet as a 2-d VECT object </li>
-<li><a href="io.c#printfacet2geom_points">qh_printfacet2geom_points</a>
-print points as a 2-d VECT object with offset </li>
-<li><a href="io.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
-print Geomview OFF for a 3-d nonsimplicial facet. </li>
-<li><a href="io.c#printfacet3geom_points">qh_printfacet3geom_points</a>
-prints a 3-d facet as OFF Geomview object. </li>
-<li><a href="io.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
-print Geomview OFF for a 3-d simplicial facet. </li>
-<li><a href="io.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
-print Geomview 4OFF file for a 4d nonsimplicial facet </li>
-<li><a href="io.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
-print Geomview 4OFF file for a 4d simplicial facet </li>
-<li><a href="io.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
-print hyperplane intersection as OFF or 4OFF </li>
-<li><a href="io.c#printvoronoi">qh_printvoronoi</a> print
-voronoi diagram in 'o' or 'G' format</li>
-</ul>
-<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iview">Geomview utility functions</a></h3>
-<ul>
-<li><a href="io.c#geomplanes">qh_geomplanes</a>
- return outer and inner planes for Geomview</li>
-<li><a href="io.c#printcentrum">qh_printcentrum</a> print
-centrum for a facet in OOGL format </li>
-<li><a href="io.c#printend4geom">qh_printend4geom</a> helper
-function for qh_printbegin/printend </li>
-<li><a href="io.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
-print Geomview OFF or 4OFF for the intersection of two
-hyperplanes in 3-d or 4-d </li>
-<li><a href="io.c#printline3geom">qh_printline3geom</a> prints a
-line as a VECT </li>
-<li><a href="io.c#printpointvect">qh_printpointvect</a>
-prints a 2-d or 3-d point as 3-d VECT's </li>
-<li><a href="io.c#printpointvect2">qh_printpointvect2</a>
-prints a 2-d or 3-d point as 2 3-d VECT's </li>
-<li><a href="io.c#printspheres">qh_printspheres</a> prints 3-d
-vertices as OFF spheres </li>
-</ul>
-<p>
-<p><!-- Navigation links --> </p>
-<hr>
-<p><b>Up:</b>
-<a href="http://www.qhull.org">Home page for
-Qhull</a> <br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
-</p>
-<p><!-- GC common information --> </p>
-<hr>
-<p><a href="http://www.geom.uiuc.edu/"><img
-src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
-Geometry Center Home Page </i></p>
-<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
-</a><br>
-Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
-</body>
-</html>
diff --git a/src/libqhullr/qh-qhull.htm b/src/libqhullr/qh-qhull.htm
deleted file mode 100644
index 4962dca..0000000
--- a/src/libqhullr/qh-qhull.htm
+++ /dev/null
@@ -1,277 +0,0 @@
-<!-- Do not edit with Front Page, it adds too many spaces -->
-<html>
-<head>
-<meta http-equiv="Content-Type"
-content="text/html; charset=iso-8859-1">
-<title>libqhull.c -- top-level functions and basic data types</title>
-</head>
-
-<body>
-<!-- Navigation links -->
-<p><a name="TOP"><b>Up:</b></a> <a
-href="http://www.qhull.org">Home page</a> for Qhull<br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
-</p>
-<hr>
-
-<h2>libqhull.c -- top-level functions and basic data types</h2>
-<blockquote>
-<p>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
-<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
-<p>This section provides an index to the top-level
-functions and base data types. The top-level header file, <tt>libqhull.h</tt>,
-contains prototypes for these functions.</p>
-</blockquote>
-<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
-<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
-&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
-&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <b>Qhull</b> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
-</p>
-<h3>Index to <a href="libqhull.c">libqhull.c</a>,
-<a href="libqhull.h">libqhull.h</a>, and
-<a href="../qhull/unix.c">unix.c</a></h3>
-<ul>
-<li><a href="#qtype">libqhull.h and unix.c data types and
-constants</a> </li>
-<li><a href="#qmacro">libqhull.h other macros</a> </li>
-<li><a href="#qfunc">Quickhull routines in call order</a> </li>
-<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
-<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
-<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
-<li><a href="#qout">Top-level routines for returning results</a></li>
-<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qtype">libqhull.h and unix.c
-data types and constants</a></h3>
-<ul>
-<li><a href="libqhull.h#flagT">flagT</a> Boolean flag as
-a bit </li>
-<li><a href="libqhull.h#boolT">boolT</a> boolean value,
-either True or False </li>
-<li><a href="libqhull.h#CENTERtype">CENTERtype</a> to
-distinguish facet-&gt;center </li>
-<li><a href="libqhull.h#qh_PRINT">qh_PRINT</a> output
-formats for printing (qh.PRINTout) </li>
-<li><a href="libqhull.h#qh_ALL">qh_ALL</a> argument flag
-for selecting everything </li>
-<li><a href="libqhull.h#qh_ERR">qh_ERR</a> Qhull exit
-codes for indicating errors </li>
-<li><a href="libqhull.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
-to distinguish error output from normal output [C++ only]</li>
-<li><a href="../qhull/unix.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
-<li><a href="../qhull/unix.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
-<li><a href="../qhull/unix.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
-<li><a href="global.c#qh_version">qh_version</a> version stamp</li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qmacro">libqhull.h other
-macros</a></h3>
-<ul>
-<li><a href="qhull_a.h#traceN">traceN</a> print trace
-message if <em>qh.IStracing &gt;= N</em>. </li>
-<li><a href="qhull_a.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
- unused variable to avoid warnings. </li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qfunc">Quickhull
-routines in call order</a></h3>
-<ul>
-<li><a href="../qhull/unix.c#main">main</a> processes the
-command line, calls qhull() to do the work, and
-exits </li>
-<li><a href="libqhull.c#qhull">qh_qhull</a> construct
-the convex hull of a set of points </li>
-<li><a href="libqhull.c#build_withrestart">qh_build_withrestart</a>
-allow restarts while calling qh_buildhull</li>
-<li><a href="poly2.c#initbuild">qh_initbuild</a>
-initialize hull and outside sets with point array</li>
-<li><a href="libqhull.c#partitionall">qh_partitionall</a>
-partition all points into outside sets </li>
-<li><a href="libqhull.c#buildhull">qh_buildhull</a>
-construct a convex hull by adding points one at a
-time </li>
-<li><a href="libqhull.c#nextfurthest">qh_nextfurthest</a>
-return next furthest point for processing </li>
-<li><a href="libqhull.c#buildtracing">qh_buildtracing</a>
-trace an iteration of buildhull </li>
-<li><a href="libqhull.c#addpoint">qh_addpoint</a> add a
-point to the convex hull </li>
-<li><a href="libqhull.c#findhorizon">qh_findhorizon</a>
-find the horizon and visible facets for a point </li>
-<li><a href="libqhull.c#partitionvisible">qh_partitionvisible</a>
-partition points from facets in qh.visible_list
-to facets in qh.newfacet_list </li>
-<li><a href="libqhull.c#partitionpoint">qh_partitionpoint</a>
-partition a point as inside, coplanar with, or
-outside a facet </li>
-<li><a href="libqhull.c#partitioncoplanar">qh_partitioncoplanar</a>
-partition coplanar point into a facet </li>
-<li><a href="libqhull.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
-<ul>
-<li><a href="global.c#freebuild">qh_freebuild</a>
-free memory used by qh_initbuild and qh_buildhull
-</li>
-<li><a href="global.c#checkflags">qh_checkflags</a>
-check flags for multiple frontends to qhull
-<li><a href="global.c#freeqhull">qh_freeqhull</a>
-free memory used by qhull </li>
-<li><a href="global.c#init_A">qh_init_A</a> called
-before error handling initialized </li>
-<li><a href="global.c#init_B">qh_init_B</a> called
-after points are defined </li>
-<li><a href="global.c#initflags">qh_initflags</a> set
-flags and constants from command line </li>
-<li><a href="rboxlib.c#rboxpoints">qh_rboxpoints</a>
-generate points for qhull </li>
-<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
-restores a saved qhull </li>
-<li><a href="global.c#save_qhull">qh_save_qhull</a>
-saves qhull for later restoring </li>
-<li><a href="user.c#user_memsizes">qh_user_memsizes</a>
-define additional quick allocation sizes
-</li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
-<ul>
-<li><a href="geom2.c#gram_schmidt">qh_gram_schmidt</a>
-implements Gram-Schmidt orthogonalization by rows </li>
-<li><a href="geom2.c#projectinput">qh_projectinput</a>
-project input along one or more dimensions +
-Delaunay projection </li>
-<li><a href="geom2.c#randommatrix">qh_randommatrix</a>
-generate a random dimXdim matrix in range (-1,1) </li>
-<li><a href="io.c#readpoints">qh_readpoints</a> read
-points from input </li>
-<li><a href="geom2.c#rotateinput">qh_rotateinput</a> rotate
-input points using row matrix </li>
-<li><a href="geom2.c#scaleinput">qh_scaleinput</a> scale
-input points using qh low_bound/high_bound </li>
-<li><a href="geom2.c#setdelaunay">qh_setdelaunay</a> project
-points to paraboloid for Delaunay triangulation </li>
-<li><a href="geom2.c#sethalfspace_all">qh_sethalfspace_all</a>
-generate dual for halfspace intersection with interior
-point </li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
-<ul>
-<li><a href="libqhull.c#addpoint">qh_addpoint</a> add
-point to convex hull </li>
-<li><a href="poly2.c#findbestfacet">qh_findbestfacet</a>
-find facet that is furthest below a point </li>
-<li><a href="poly2.c#findfacet_all">qh_findfacet_all</a>
-exhaustive search for facet below a point </li>
-<li><a href="libqhull.c#qhull">qh_qhull</a> construct
-the convex hull of a set of points </li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
-<ul>
-<li><a href="stat.c#collectstatistics">qh_collectstatistics</a>
-collect statistics for qh.facet_list </li>
-<li><a href="poly2.c#nearvertex">qh_nearvertex</a>
-return nearest vertex to point </li>
-<li><a href="poly2.c#point">qh_point</a> return point
-for a point ID </li>
-<li><a href="poly2.c#pointfacet">qh_pointfacet</a>
-return temporary set of facets indexed by point
-ID </li>
-<li><a href="poly.c#pointid">qh_pointid</a> return ID
-for a point</li>
-<li><a href="poly2.c#pointvertex">qh_pointvertex</a>
-return vertices (if any) for all points</li>
-<li><a href="stat.c#printallstatistics">qh_printallstatistics</a>
-print all statistics </li>
-<li><a href="io.c#printneighborhood">qh_printneighborhood</a>
-print neighborhood of one or two facets </li>
-<li><a href="libqhull.c#printsummary">qh_printsummary</a>
-print summary </li>
-<li><a href="io.c#produce_output">qh_produce_output</a>
-print the results of qh_qhull() </li>
-<li><a href="poly2.c#setvoronoi_all">qh_setvoronoi_all</a>
-compute Voronoi centers for all facets </li>
-</ul>
-
-<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
-<ul>
-<li><a href="io.c#dfacet">dfacet</a> print facet by
-ID from debugger </li>
-<li><a href="io.c#dvertex">dvertex</a> print vertex
-by ID from debugger </li>
-<li><a href="poly2.c#check_output">qh_check_output</a>
-check output </li>
-<li><a href="poly2.c#check_points">qh_check_points</a>
-verify that all points are inside the convex hull
-</li>
-<li><a href="user.c#errexit">qh_errexit</a> report
-error with a facet and a ridge</li>
-<li><a href="libqhull.c#errexit2">qh_errexit2</a> report
-error with two facets </li>
-<li><a href="user.c#errprint">qh_errprint</a> print
-erroneous facets, ridge, and vertex </li>
-<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
-print all fields for a list of facets </li>
-</ul>
-
-<p><!-- Navigation links --> </p>
-<hr>
-<p><b>Up:</b>
-<a href="http://www.qhull.org">Home page for
-Qhull</a> <br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
-</p>
-<p><!-- GC common information --> </p>
-<hr>
-<p><a href="http://www.geom.uiuc.edu/"><img
-src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
-Geometry Center Home Page </i></p>
-<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
-</a><br>
-Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
-</body>
-</html>
diff --git a/src/libqhullr/qh-user.htm b/src/libqhullr/qh-user.htm
deleted file mode 100644
index 1525f2b..0000000
--- a/src/libqhullr/qh-user.htm
+++ /dev/null
@@ -1,265 +0,0 @@
-<!-- Do not edit with Front Page, it adds too many spaces -->
-<html>
-<head>
-<meta http-equiv="Content-Type"
-content="text/html; charset=iso-8859-1">
-<title>user.c -- user-definable operations</title>
-</head>
-
-<body>
-<!-- Navigation links -->
-<p><a name="TOP"><b>Up:</b></a> <a
-href="http://www.qhull.org">Home page</a> for Qhull<br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
-&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
-&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
-&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
-&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
-</p>
-<hr>
-<h2>user.c -- user-definable operations</h2>
-<blockquote>
-<p>This section contains functions and constants that the
-user may want to change. </p>
-
-</blockquote>
-<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
-<hr>
-<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
-<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
-&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
-&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
-&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
-&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <b>User</b>
-</p>
-<h3>Index to <a href="user.c">user.c</a>, <a href="usermem.c">usermem.c</a>, <a href="userprintf.c">userprintf.c</a>, <a href="userprintf_rbox.c">userprintf_rbox.c</a> and
-<a href="user.h">user.h</a></h3>
-<ul>
-<li><a href="#qulllib">qhull library constants</a></li>
-<li><a href="#utype">user.h data types and
-configuration macros</a> </li>
-<li><a href="#ujoggle">joggle constants</a></li>
-<li><a href="#uperform">performance related constants</a></li>
-<li><a href="#umemory">memory constants</a></li>
-<li><a href="#ucond">conditional compilation</a></li>
-<li><a href="#umerge">merge constants</a> </li>
-<li><a href="#ufunc">user.c functions</a> </li>
-<li><a href="#u2func">usermem.c functions</a> </li>
-<li><a href="#u3func">userprintf.c functions</a> </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="qulllib">Qhull library constants</a></h3>
-<ul>
-<li><a href="user.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
-<li><a href="user.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
-<li><a href="user.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
-</ul>
-
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="utype">user.h data
-types and configuration macros</a></h3>
-<ul>
-<li><a href="user.h#realT">realT, qh_REAL...</a> size
-of floating point numbers </li>
-<li><a href="user.h#countT">countT, COUNTmax</a> size
-of counts and identifiers, typically 'int' or 'long long' </li>
-<li><a href="user.h#CPUclock">qh_CPUclock</a> clock()
-function for reporting the total time spent by
-Qhull </li>
-<li><a href="user.h#RANDOM">qh_RANDOM...</a> random
-number generator </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="udef">definition constants</a></h3>
-<ul>
-<li><a href="user.h#DEFAULTbox">qh_DEFAULTbox</a>
-define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
-<li><a href="user.h#INFINITE">qh_INFINITE</a> on
-output, indicates Voronoi center at infinity </li>
-<li><a href="user.h#ORIENTclock">qh_ORIENTclock</a>
-define convention for orienting facets</li>
-<li><a href="user.h#ZEROdelaunay">qh_ZEROdelaunay</a>
-define facets that are ignored in Delaunay triangulations</li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ujoggle">joggle constants</a></h3>
-<ul>
-<li><a href="user.h#JOGGLEagain">qh_JOGGLEagain</a>
-how often to retry before using qh_JOGGLEmaxincrease
-again </li>
-<li><a href="user.h#JOGGLEdefault">qh_JOGGLEdefault</a>
-default value for qh.JOGGLEmax for 'QP' </li>
-<li><a href="user.h#JOGGLEincrease">qh_JOGGLEincrease</a>
-factor to increase qh.JOGGLEmax on retrys for
-'QPn' </li>
-<li><a href="user.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
-for increasing qh.JOGGLEmax relative to
-qh.MAXwidth </li>
-<li><a href="user.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
-report error if this many retries </li>
-<li><a href="user.h#JOGGLEretry">qh_JOGGLEretry</a>
-how often to retry before using qh_JOGGLEmax </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="uperform">performance
-related constants</a></h3>
-<ul>
-<li><a href="user.h#HASHfactor">qh_HASHfactor</a>
-total/used hash slots </li>
-<li><a href="user.h#INITIALmax">qh_INITIALmax</a> if
-dim &gt;= qh_INITIALmax, use min/max coordinate
-points for initial simplex </li>
-<li><a href="user.h#INITIALsearch">qh_INITIALsearch</a>
-if qh.INITIALmax, search points up to this
-dimension </li>
-<li><a href="user.h#NOtrace">qh_NOtrace</a> disallow
-tracing </li>
-<li><a href="user.h#VERIFYdirect">qh_VERIFYdirect</a>
-'Tv' verifies all <em>points X facets</em> if op
-count is smaller </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="umemory">memory constants</a></h3>
-<ul>
-<li><a href="user.h#MEMalign">qh_MEMalign</a> memory
-alignment for qh_meminitbuffers() in global.c </li>
-<li><a href="user.h#MEMbufsize">qh_MEMbufsize</a>
-size of additional memory buffers </li>
-<li><a href="user.h#MEMinitbuf">qh_MEMinitbuf</a>
-size of initial memory buffer </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ucond">conditional compilation</a></h3>
-<ul>
-<li><a href="user.h#compiler">compiler</a> defined symbols,
-e.g., _STDC_ and _cplusplus
-
-<li><a href="user.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
- compute furthest distance to an outside point instead of storing it with the facet
-<li><a href="user.h#KEEPstatistics">qh_KEEPstatistics</a>
- enable statistic gathering and reporting with option 'Ts'
-<li><a href="user.h#MAXoutside">qh_MAXoutside</a>
-record outer plane for each facet
-<li><a href="user.h#NOmerge">qh_NOmerge</a>
-disable facet merging
-<li><a href="user.h#NOtrace">qh_NOtrace</a>
-disable tracing with option 'T4'
-<li><a href="user.h#QHpointer">qh_QHpointer</a>
-access global data with pointer or static structure
-<li><a href="user.h#QUICKhelp">qh_QUICKhelp</a>
-use abbreviated help messages, e.g., for degenerate inputs
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="umerge">merge
-constants</a></h3>
-<ul>
-<li><a href="user.h#BESTcentrum">qh_BESTcentrum</a>
-when does qh_findbestneighbor() test centrums? </li>
-<li><a href="user.h#BESTnonconvex">qh_BESTnonconvex</a>
-when does qh_findbestneighbor() test nonconvex
-ridges only? </li>
-<li><a href="user.h#COPLANARratio">qh_COPLANARratio</a>
-what is qh.MINvisible? </li>
-<li><a href="user.h#DIMreduceBuild">qh_DIMreduceBuild</a>
-max dimension for vertex reduction </li>
-<li><a href="user.h#DIMmergeVertex">qh_DIMmergeVertex</a>
-max dimension for vertex merging </li>
-<li><a href="user.h#DISToutside">qh_DISToutside</a>
-when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall</li>
-<li><a href="user.h#MAXnarrow">qh_MAXnarrow</a> max.
-cosine for qh.NARROWhull </li>
-<li><a href="user.h#MAXnewcentrum">qh_MAXnewcentrum</a>
-when does qh_reducevertices_centrum() reset the
-centrum? </li>
-<li><a href="user.h#MAXnewmerges">qh_MAXnewmerges</a>
-when does qh_merge_nonconvex() call
-qh_reducevertices_centrums? </li>
-<li><a href="user.h#RATIOnearinside">qh_RATIOnearinside</a>
-ratio for retaining inside points for
-qh_check_maxout() </li>
-<li><a href="user.h#SEARCHdist">qh_SEARCHdist</a>
-when is facet coplanar with the best facet for qh_findbesthorizon</li>
-<li><a href="user.h#USEfindbestnew">qh_USEfindbestnew</a>
-when to use qh_findbestnew for qh_partitionpoint()</li>
-<li><a href="user.h#WIDEcoplanar">qh_WIDEcoplanar</a>
-what is a WIDEfacet? </li>
-<li><a href="user.h#WARNnarrow">qh_WARNnarrow</a>
-max. cosine to warn about qh.NARROWhull </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ufunc">user.c
-functions</a></h3>
-<ul>
-<li><a href="user.c#errexit">qh_errexit</a> report
-error and exit qhull()</li>
-<li><a href="user.c#errprint">qh_errprint</a> print
-information about facets and ridges </li>
-<li><a href="user.c#new_qhull">qh_new_qhull</a> call qhull on an array
-of points</li>
-<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
-print all fields of all facets </li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="u2func">usermem.c
-functions</a></h3>
-<ul>
-<li><a href="usermem.c#qh_exit">qh_exit</a> exit program, same as exit().</li>
-<li><a href="usermem.c#qh_free">qh_free</a> free memory, same as free().</li>
-<li><a href="usermem.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
-</ul>
-
-<h3><a href="qh-user.htm#TOC">&#187;</a><a name="u3func">userprintf.c
- and userprintf_rbox,c functions</a></h3>
-<ul>
-<li><a href="userprintf.c#qh_fprintf">qh_fprintf</a> print
-information from Qhull, sames as fprintf(). </li>
-<li><a href="userprintf_rbox.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
-information from Rbox, sames as fprintf(). </li>
-</ul>
-
-<p><!-- Navigation links --> </p>
-<hr>
-<p><b>Up:</b>
-<a href="http://www.qhull.org">Home page for
-Qhull</a> <br>
-<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
-<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
-&#149; <a href="../../html/qh-quick.htm#options">Options</a>
-&#149; <a href="../../html/qh-opto.htm#output">Output</a>
-&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
-&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
-&#149; <a href="../../html/qh-optp.htm#print">Print</a>
-&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
-&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
-&#149; <a href="../../html/qh-optt.htm#trace">Trace</a><br>
-<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
-<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
-<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
-<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
-&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
-&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
-&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
-&#149; <a href="qh-user.htm">User</a><br>
-</p>
-<p><!-- GC common information --> </p>
-<hr>
-<p><a href="http://www.geom.uiuc.edu/"><img
-src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
-Geometry Center Home Page </i></p>
-<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
-</a><br>
-Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
-</body>
-</html>
diff --git a/src/libqhullstaticr/libqhullstaticr.pro b/src/libqhullstatic_r/libqhullstatic_r.pro
similarity index 83%
rename from src/libqhullstaticr/libqhullstaticr.pro
rename to src/libqhullstatic_r/libqhullstatic_r.pro
index 2430e2d..2f5bf4d 100644
--- a/src/libqhullstaticr/libqhullstaticr.pro
+++ b/src/libqhullstatic_r/libqhullstatic_r.pro
@@ -1,20 +1,21 @@
# -------------------------------------------------
-# libqhullstaticr.pro -- Qt project for Qhull static library
-# Reentrant code
+# 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/libqhullstaticp/libqhullstaticp.pro b/src/libqhullstaticp/libqhullstaticp.pro
deleted file mode 100644
index fd4e38d..0000000
--- a/src/libqhullstaticp/libqhullstaticp.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# -------------------------------------------------
-# libqhullstaticp.pro -- Qhull static library with qh_qhPointer
-# -------------------------------------------------
-
-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_pd
- OBJECTS_DIR = Debug
-}else:build_pass:CONFIG(release, debug|release) {
- TARGET = qhullstatic_p
- OBJECTS_DIR = Release
-}
-
-DEFINES += qh_QHpointer # libqhull/user.h
-
diff --git a/src/qconvex/qconvex.c b/src/qconvex/qconvex.c
index d6118ff..8e8c64c 100644
--- a/src/qconvex/qconvex.c
+++ b/src/qconvex/qconvex.c
@@ -1,336 +1,322 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull/mem.h"
+#include "libqhull/qset.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
qh_prompt2
synopsis for qhull
*/
char qh_prompt2[]= "\n\
qconvex- compute the convex hull. Qhull %s\n\
input (stdin): dimension, number of points, point coordinates\n\
comments start with a non-numeric character\n\
\n\
options (qconvex.htm):\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Tv - verify result: structure, convexity, and point inclusion\n\
. - concise list of all options\n\
- - one-line description of all options\n\
\n\
output options (subset):\n\
s - summary of results (default)\n\
i - vertices incident to each facet\n\
n - normals with offsets\n\
p - vertex coordinates (includes coplanar points if 'Qc')\n\
Fx - extreme points (convex hull vertices)\n\
FA - 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) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="main">-</a>
main( argc, argv )
processes the command line, calls qhull() to do the work, and exits
design:
initializes data structures
reads points
finishes initialization
computes convex hull and other structures
checks the result
writes the output
frees memory
*/
int main(int argc, char *argv[]) {
int curlong, totlong; /* used !qh_NOmem */
int exitcode, numpoints, dim;
coordT *points;
boolT ismalloc;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
if (!exitcode) {
+ qh 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( True);
#else
qh_freeqhull( False);
qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qconvex/qconvex.c b/src/qconvex/qconvex_r.c
similarity index 88%
copy from src/qconvex/qconvex.c
copy to src/qconvex/qconvex_r.c
index d6118ff..a7deb0f 100644
--- a/src/qconvex/qconvex.c
+++ b/src/qconvex/qconvex_r.c
@@ -1,336 +1,323 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull_r/mem_r.h"
+#include "libqhull_r/qset_r.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
qh_prompt2
synopsis for qhull
*/
char qh_prompt2[]= "\n\
qconvex- compute the convex hull. Qhull %s\n\
input (stdin): dimension, number of points, point coordinates\n\
comments start with a non-numeric character\n\
\n\
options (qconvex.htm):\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Tv - verify result: structure, convexity, and point inclusion\n\
. - concise list of all options\n\
- - one-line description of all options\n\
\n\
output options (subset):\n\
s - summary of results (default)\n\
i - vertices incident to each facet\n\
n - normals with offsets\n\
p - vertex coordinates (includes coplanar points if 'Qc')\n\
Fx - extreme points (convex hull vertices)\n\
FA - 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) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="main">-</a>
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;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
- qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
- exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ 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_checkflags(qh qhull_command, hidden_options);
- qh_initflags(qh qhull_command);
- points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ 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("Qxact_merge", NULL, NULL);
- qh MERGEexact= True; /* 'Qx' always */
+ qh_option(qh, "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();
+ 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 */
+ qh->NOerrexit= True; /* no more setjmp */
#ifdef qh_NOmem
- qh_freeqhull( True);
+ qh_freeqhull(qh, True);
#else
- qh_freeqhull( False);
- qh_memfreeshort(&curlong, &totlong);
+ qh_freeqhull(qh, False);
+ qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qdelaunay/qdelaun.c b/src/qdelaunay/qdelaun.c
index a67c0ee..44411ad 100644
--- a/src/qdelaunay/qdelaun.c
+++ b/src/qdelaunay/qdelaun.c
@@ -1,325 +1,311 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull/mem.h"
+#include "libqhull/qset.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
qh_prompt2
synopsis for qhull
*/
char qh_prompt2[]= "\n\
qdelaunay- compute the Delaunay triangulation. Qhull %s\n\
input (stdin): dimension, number of points, point coordinates\n\
comments start with a non-numeric character\n\
\n\
options (qdelaun.htm):\n\
Qu - furthest-site Delaunay triangulation\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Tv - verify result: structure, convexity, and in-circle test\n\
. - concise list of all options\n\
- - one-line description of all options\n\
\n\
output options (subset):\n\
s - summary of results (default)\n\
i - vertices incident to each Delaunay region\n\
Fx - extreme points (vertices of the convex hull)\n\
o - OFF format (shows the points lifted to a paraboloid)\n\
G - Geomview output (2-d and 3-d points lifted to a paraboloid)\n\
m - Mathematica output (2-d inputs lifted to a paraboloid)\n\
QVn - print Delaunay regions that include point n, -n if not\n\
TO file- output results to file, may be enclosed in single quotes\n\
\n\
examples:\n\
rbox c P0 D2 | qdelaunay s o rbox c P0 D2 | qdelaunay i\n\
rbox c P0 D2 | qdelaunay Fv rbox c P0 D2 | qdelaunay s Qu Fv\n\
rbox c G1 d D2 | qdelaunay s i rbox c G1 d D2 | qdelaunay Qt\n\
rbox M3,4 z 100 D2 | qdelaunay s rbox M3,4 z 100 D2 | qdelaunay s Qt\n\
\n\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
main( argc, argv )
processes the command line, calls qhull() to do the work, and exits
design:
initializes data structures
reads points
finishes initialization
computes convex hull and other structures
checks the result
writes the output
frees memory
*/
int main(int argc, char *argv[]) {
int curlong, totlong; /* used !qh_NOmem */
int exitcode, numpoints, dim;
coordT *points;
boolT ismalloc;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
if (!exitcode) {
+ qh 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( True);
#else
qh_freeqhull( False);
qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qdelaunay/qdelaun.c b/src/qdelaunay/qdelaun_r.c
similarity index 86%
copy from src/qdelaunay/qdelaun.c
copy to src/qdelaunay/qdelaun_r.c
index a67c0ee..4d02fd3 100644
--- a/src/qdelaunay/qdelaun.c
+++ b/src/qdelaunay/qdelaun_r.c
@@ -1,325 +1,312 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull_r/mem_r.h"
+#include "libqhull_r/qset_r.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
qh_prompt2
synopsis for qhull
*/
char qh_prompt2[]= "\n\
qdelaunay- compute the Delaunay triangulation. Qhull %s\n\
input (stdin): dimension, number of points, point coordinates\n\
comments start with a non-numeric character\n\
\n\
options (qdelaun.htm):\n\
Qu - furthest-site Delaunay triangulation\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Tv - verify result: structure, convexity, and in-circle test\n\
. - concise list of all options\n\
- - one-line description of all options\n\
\n\
output options (subset):\n\
s - summary of results (default)\n\
i - vertices incident to each Delaunay region\n\
Fx - extreme points (vertices of the convex hull)\n\
o - OFF format (shows the points lifted to a paraboloid)\n\
G - Geomview output (2-d and 3-d points lifted to a paraboloid)\n\
m - Mathematica output (2-d inputs lifted to a paraboloid)\n\
QVn - print Delaunay regions that include point n, -n if not\n\
TO file- output results to file, may be enclosed in single quotes\n\
\n\
examples:\n\
rbox c P0 D2 | qdelaunay s o rbox c P0 D2 | qdelaunay i\n\
rbox c P0 D2 | qdelaunay Fv rbox c P0 D2 | qdelaunay s Qu Fv\n\
rbox c G1 d D2 | qdelaunay s i rbox c G1 d D2 | qdelaunay Qt\n\
rbox M3,4 z 100 D2 | qdelaunay s rbox M3,4 z 100 D2 | qdelaunay s Qt\n\
\n\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
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;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
- qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
- exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ 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_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);
+ 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("Qxact_merge", NULL, NULL);
- qh MERGEexact= True; /* 'Qx' always */
+ qh_option(qh, "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();
+ 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 */
+ qh->NOerrexit= True; /* no more setjmp */
#ifdef qh_NOmem
- qh_freeqhull( True);
+ qh_freeqhull(qh, True);
#else
- qh_freeqhull( False);
- qh_memfreeshort(&curlong, &totlong);
+ qh_freeqhull(qh, False);
+ qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qhalf/qhalf.c b/src/qhalf/qhalf.c
index 2bd8286..153993a 100644
--- a/src/qhalf/qhalf.c
+++ b/src/qhalf/qhalf.c
@@ -1,326 +1,312 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull/mem.h"
+#include "libqhull/qset.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
qh_prompt2
synopsis for qhull
*/
char qh_prompt2[]= "\n\
qhalf- halfspace intersection about a point. Qhull %s\n\
input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset\n\
comments start with a non-numeric character\n\
\n\
options (qhalf.htm):\n\
Hn,n - specify coordinates of interior point\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Tv - verify result: structure, convexity, and redundancy\n\
. - concise list of all options\n\
- - one-line description of all options\n\
\n\
output options (subset):\n\
s - summary of results (default)\n\
Fp - intersection coordinates\n\
Fv - non-redundant halfspaces incident to each intersection\n\
Fx - non-redundant halfspaces\n\
o - OFF file format (dual convex hull)\n\
G - Geomview output (dual convex hull)\n\
m - Mathematica output (dual convex hull)\n\
QVn - print intersections for halfspace n, -n if not\n\
TO file - output results to file, may be enclosed in single quotes\n\
\n\
examples:\n\
rbox d | qconvex FQ n | qhalf s H0,0,0 Fp\n\
rbox c | qconvex FQ FV n | qhalf s i\n\
rbox c | qconvex FQ FV n | qhalf s o\n\
\n\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
main( argc, argv )
processes the command line, calls qhull() to do the work, and exits
design:
initializes data structures
reads points
finishes initialization
computes convex hull and other structures
checks the result
writes the output
frees memory
*/
int main(int argc, char *argv[]) {
int curlong, totlong; /* used !qh_NOmem */
int exitcode, numpoints, dim;
coordT *points;
boolT ismalloc;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
if (!exitcode) {
+ qh 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( True);
#else
qh_freeqhull( False);
qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qhalf/qhalf.c b/src/qhalf/qhalf_r.c
similarity index 86%
copy from src/qhalf/qhalf.c
copy to src/qhalf/qhalf_r.c
index 2bd8286..b1302df 100644
--- a/src/qhalf/qhalf.c
+++ b/src/qhalf/qhalf_r.c
@@ -1,326 +1,313 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull_r/mem_r.h"
+#include "libqhull_r/qset_r.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
qh_prompt2
synopsis for qhull
*/
char qh_prompt2[]= "\n\
qhalf- halfspace intersection about a point. Qhull %s\n\
input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset\n\
comments start with a non-numeric character\n\
\n\
options (qhalf.htm):\n\
Hn,n - specify coordinates of interior point\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Tv - verify result: structure, convexity, and redundancy\n\
. - concise list of all options\n\
- - one-line description of all options\n\
\n\
output options (subset):\n\
s - summary of results (default)\n\
Fp - intersection coordinates\n\
Fv - non-redundant halfspaces incident to each intersection\n\
Fx - non-redundant halfspaces\n\
o - OFF file format (dual convex hull)\n\
G - Geomview output (dual convex hull)\n\
m - Mathematica output (dual convex hull)\n\
QVn - print intersections for halfspace n, -n if not\n\
TO file - output results to file, may be enclosed in single quotes\n\
\n\
examples:\n\
rbox d | qconvex FQ n | qhalf s H0,0,0 Fp\n\
rbox c | qconvex FQ FV n | qhalf s i\n\
rbox c | qconvex FQ FV n | qhalf s o\n\
\n\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
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;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
- qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
- exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ 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_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, "\
+ 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_ERRinput, NULL, NULL);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
}
- points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
if (dim >= 5) {
- qh_option("Qxact_merge", NULL, NULL);
- qh MERGEexact= True; /* 'Qx' always */
+ qh_option(qh, "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();
+ 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 */
+ qh->NOerrexit= True; /* no more setjmp */
#ifdef qh_NOmem
- qh_freeqhull( True);
+ qh_freeqhull(qh, True);
#else
- qh_freeqhull( False);
- qh_memfreeshort(&curlong, &totlong);
+ qh_freeqhull(qh, False);
+ qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qhull-all.pro b/src/qhull-all.pro
index 8bbab78..1d3a0ac 100644
--- a/src/qhull-all.pro
+++ b/src/qhull-all.pro
@@ -1,95 +1,94 @@
# -------------------------------------------------
# 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
-# ../build> qmake -tp vc -r ../src/qhull-all.pro
-# Need to add Build Dependencies, disable rtti, rename targets to qhull.dll, qhull6_p.dll and qhull6_pd.dll
+# 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 += libqhullr #shared library for reentrant code
-SUBDIRS += user_eg #user program linked to libqhullr (libqhullr)
+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 += libqhullstaticr #static library with reentrant code
-SUBDIRS += qhull #qhull programs linked to libqhullstatic
-SUBDIRS += qconvex
+SUBDIRS += qhull #qhull program linked to libqhullstatic_r
+SUBDIRS += rbox
+SUBDIRS += qconvex #qhull programs linked to libqhullstatic
SUBDIRS += qdelaunay
SUBDIRS += qhalf
SUBDIRS += qvoronoi
-SUBDIRS += rbox
-SUBDIRS += qhullr #qhull program linked to libqhullstatic_r
-SUBDIRS += rboxr #rbox program linked to libqhullstatic_r
-SUBDIRS += user_eg2 #user program linked to libqhullr
-SUBDIRS += testqset #test program for qset.c with mem.c
-SUBDIRS += testqsetr #test program for qset_r.c with mem_r.c
-SUBDIRS += libqhullcpp #static library for C++ interface with libqhullstaticr
-SUBDIRS += user_eg3 #user program with libqhullcpp and libqhullstaticr
-SUBDIRS += qhulltest #test program with Qt, libqhullcpp, and libqhullstaticr
+SUBDIRS += user_eg #user programs linked to libqhull_r
+SUBDIRS += user_eg2
+SUBDIRS += user_eg3 #user program with libqhullcpp and libqhullstatic_r
-# Deprecated projects
-SUBDIRS += libqhull #shared library
-SUBDIRS += libqhullp #shared library with qh_QHpointer (libqhull/user.h)
-SUBDIRS += libqhullstatic #static library
-SUBDIRS += libqhullstaticp #static library with qh_QHpointer
-SUBDIRS += qhullptest #test program with Qt, libqhullpcpp, and libqhullstaticp
-SUBDIRS += libqhullpcpp #static library for C++ interface with libqhullstaticp
-SUBDIRS += user_egp #user program linked to libqhull6_p (libqhullp)
-SUBDIRS += user_eg2p #user program linked to libqhull
-SUBDIRS += user_eg3p #user program with libqhullcpp and libqhullstaticp
+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 += ../libqhull/DEPRECATED.txt
-OTHER_FILES += ../libqhullp/DEPRECATED.txt
-OTHER_FILES += ../libqhullpcpp/DEPRECATED.txt
-OTHER_FILES += ../qhullptest/DEPRECATED.txt
-OTHER_FILES += ../libqhull/qhull-exports.def
-OTHER_FILES += ../libqhullp/qhull_p-exports.def
-OTHER_FILES += ../libqhullr/qhull_r-exports.def
+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-app-c.pri b/src/qhull-app-c.pri
index 20b064f..05e5a00 100644
--- a/src/qhull-app-c.pri
+++ b/src/qhull-app-c.pri
@@ -1,24 +1,24 @@
# -------------------------------------------------
# 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 += ../libqhull
+INCLUDEPATH += ..
CONFIG += qhull_warn_conversion
diff --git a/src/qhull-app-c_r.pri b/src/qhull-app-c_r.pri
index cd861f3..9c2ef56 100644
--- a/src/qhull-app-c_r.pri
+++ b/src/qhull-app-c_r.pri
@@ -1,24 +1,26 @@
# -------------------------------------------------
-# qhull-app-c_r.pri -- Qt include project for reentrant C qhull applications linked to qhullstatic_r
+# 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 += ../libqhullr
+INCLUDEPATH += ..
CONFIG += qhull_warn_conversion
diff --git a/src/qhull-app-cpp.pri b/src/qhull-app-cpp.pri
index 5a3d07a..a6f17d8 100644
--- a/src/qhull-app-cpp.pri
+++ b/src/qhull-app-cpp.pri
@@ -1,24 +1,23 @@
# -------------------------------------------------
# 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 += ../libqhullcpp
-INCLUDEPATH += ../../src # "libqhullr/qhull_a.h"
+INCLUDEPATH += ../../src # "libqhull_r/qhull_a.h"
diff --git a/src/qhull-app-cpp_p.pri b/src/qhull-app-cpp_p.pri
deleted file mode 100644
index 03a92e4..0000000
--- a/src/qhull-app-cpp_p.pri
+++ /dev/null
@@ -1,26 +0,0 @@
-# -------------------------------------------------
-# qhull-app-cpp_p.pri -- Deprecated Qt include project for qhull as C++ with qh_QHpointer
-# -------------------------------------------------
-
-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_pd
- LIBS += -lqhullstatic_pd # 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_p
- LIBS += -lqhullstatic_p # Must be last, otherwise qh_fprintf,etc. are loaded from here instead of qhullcpp.lib
- OBJECTS_DIR = Release
-}
-win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
-
-DEFINES += qh_QHpointer # libqhull/user.h
-
-INCLUDEPATH += ../libqhullpcpp
-INCLUDEPATH += ../../src # "libqhull/qhull_a.h"
diff --git a/src/qhull-app-shared_r.pri b/src/qhull-app-shared_r.pri
index 60ad2e8..e55c1a6 100644
--- a/src/qhull-app-shared_r.pri
+++ b/src/qhull-app-shared_r.pri
@@ -1,27 +1,29 @@
# -------------------------------------------------
-# qhull-app-shared_r.pri -- Qt include project for reentrant C qhull applications linked with libqhull (shared library)
+# 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 # libqhullr/user.h
+win32-msvc* : DEFINES += qh_dllimport # libqhull_r/user.h
-INCLUDEPATH += ../libqhullr
+INCLUDEPATH += ..
CONFIG += qhull_warn_conversion
diff --git a/src/qhull-app-sharedp.pri b/src/qhull-app-sharedp.pri
deleted file mode 100644
index d640d0f..0000000
--- a/src/qhull-app-sharedp.pri
+++ /dev/null
@@ -1,29 +0,0 @@
-# -------------------------------------------------
-# qhull-app-sharedp.pri -- Deprecated Qt include project for C qhull applications linked with libqhull6_p
-# Compile code with -Dqh_QHpointer
-# -------------------------------------------------
-
-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_pd
- OBJECTS_DIR = Debug
-}else:build_pass:CONFIG(release, debug|release){
- LIBS += -lqhull_p
- OBJECTS_DIR = Release
-}
-win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
-
-DEFINES += qh_QHpointer # libqhull/user.h
-win32-msvc* : DEFINES += qh_QHpointer_dllimport # libqhull/user.h
-
-INCLUDEPATH += ../libqhull
-CONFIG += qhull_warn_conversion
-
-
diff --git a/src/qhull-libqhull-src.pri b/src/qhull-libqhull-src.pri
index cfa19cf..e7aff3f 100644
--- a/src/qhull-libqhull-src.pri
+++ b/src/qhull-libqhull-src.pri
@@ -1,36 +1,39 @@
# -------------------------------------------------
# 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-libqhull-src_r.pri b/src/qhull-libqhull-src_r.pri
index 110fb8e..3b53291 100644
--- a/src/qhull-libqhull-src_r.pri
+++ b/src/qhull-libqhull-src_r.pri
@@ -1,35 +1,39 @@
# -------------------------------------------------
-# qhull-libqhull-src_r.pri -- Qt include project for reentrant libqhullr sources and headers
+# 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
-SOURCES += ../libqhullr/global_r.c
-SOURCES += ../libqhullr/stat_r.c
-SOURCES += ../libqhullr/geom2_r.c
-SOURCES += ../libqhullr/poly2_r.c
-SOURCES += ../libqhullr/merge_r.c
-SOURCES += ../libqhullr/libqhull_r.c
-SOURCES += ../libqhullr/geom_r.c
-SOURCES += ../libqhullr/poly_r.c
-SOURCES += ../libqhullr/qset_r.c
-SOURCES += ../libqhullr/mem_r.c
-SOURCES += ../libqhullr/random_r.c
-SOURCES += ../libqhullr/usermem_r.c
-SOURCES += ../libqhullr/userprintf_r.c
-SOURCES += ../libqhullr/io_r.c
-SOURCES += ../libqhullr/user_r.c
-SOURCES += ../libqhullr/rboxlib_r.c
-SOURCES += ../libqhullr/userprintf_rbox_r.c
-HEADERS += ../libqhullr/geom_r.h
-HEADERS += ../libqhullr/io_r.h
-HEADERS += ../libqhullr/libqhull_r.h
-HEADERS += ../libqhullr/mem_r.h
-HEADERS += ../libqhullr/merge_r.h
-HEADERS += ../libqhullr/poly_r.h
-HEADERS += ../libqhullr/random_r.h
-HEADERS += ../libqhullr/qhull_ra.h
-HEADERS += ../libqhullr/qset_r.h
-HEADERS += ../libqhullr/stat_r.h
-HEADERS += ../libqhullr/user_r.h
+# 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-warn.pri b/src/qhull-warn.pri
index 42d6d56..4308e34 100644
--- a/src/qhull-warn.pri
+++ b/src/qhull-warn.pri
@@ -1,57 +1,57 @@
# -------------------------------------------------
# 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 = 6.3.1
-qhull_SOVERSION = 6
+# VERSION = 7.0.1
+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/qhull.pro b/src/qhull/qhull.pro
index e70d146..8393728 100644
--- a/src/qhull/qhull.pro
+++ b/src/qhull/qhull.pro
@@ -1,9 +1,9 @@
# -------------------------------------------------
-# qhull.pro -- Qt project file for qhull.exe
+# qhull.pro -- Qt project file for qhull.exe with libqhullstatic_r
# -------------------------------------------------
-include(../qhull-app-c.pri)
+include(../qhull-app-c_r.pri)
TARGET = qhull
-SOURCES += unix.c
+SOURCES += unix_r.c
diff --git a/src/qhull/unix.c b/src/qhull/unix.c
index 7acef85..82306af 100644
--- a/src/qhull/unix.c
+++ b/src/qhull/unix.c
@@ -1,382 +1,366 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/qhull/unix.c#7 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/qhull/unix.c#11 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
-#include "mem.h"
-#include "qset.h"
-#include "libqhull.h"
+#include "libqhull/mem.h"
+#include "libqhull/qset.h"
+#include "libqhull/libqhull.h"
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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 preceeded by a single interior point ('H').\n\
\n\
options:\n\
d - Delaunay triangulation by lifting points to a paraboloid\n\
d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
v - Voronoi diagram (dual of the Delaunay triangulation)\n\
v Qu - furthest-site Voronoi diagram\n\
Hn,n,... - halfspace intersection about point [n,n,0,...]\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Qc - keep coplanar points with nearest facet\n\
Qi - keep interior points with nearest facet\n\
\n\
Qhull control options:\n\
Qbk:n - scale coord k so that low bound is n\n\
QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
QbB - scale input to unit cube centered at the origin\n\
Qbb - scale last coordinate to [0,m] for Delaunay triangulations\n\
Qbk:0Bk:0 - remove k-th coordinate from input\n\
QJn - randomly joggle input in range [-n,n]\n\
QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
%s%s%s%s"; /* split up qh_prompt for Visual C++ */
char qh_promptb[]= "\
Qf - partition point to furthest outside facet\n\
Qg - only build good facets (needs 'QGn', 'QVn', or 'PdD')\n\
Qm - only process points that would increase max_outside\n\
Qr - process random outside points instead of furthest ones\n\
Qs - search all points for the initial simplex\n\
Qu - for 'd' or 'v', compute upper hull without point at-infinity\n\
returns furthest-site Delaunay triangulation\n\
Qv - test vertex neighbors for convexity\n\
Qx - exact pre-merges (skips coplanar and angle-coplanar facets)\n\
Qz - add point-at-infinity to Delaunay triangulation\n\
QGn - good facet if visible from point n, -n for not visible\n\
QVn - good facet if it includes point n, -n if not\n\
Q0 - turn off default premerge with 'C-0'/'Qx'\n\
Q1 - sort merges by type instead of angle\n\
Q2 - merge all non-convex at once instead of independent sets\n\
Q3 - do not merge redundant vertices\n\
Q4 - avoid old->new merges\n\
Q5 - do not correct outer planes at end of qhull\n\
Q6 - do not pre-merge concave or coplanar facets\n\
Q7 - depth-first processing instead of breadth-first\n\
Q8 - do not process near-inside points\n\
Q9 - process furthest of furthest points\n\
Q10 - no special processing for narrow distributions\n\
Q11 - copy normals and recompute centrums for tricoplanar facets\n\
\n\
";
char qh_promptc[]= "\
Topts- Trace options:\n\
T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
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\
\n\
Output options (subset):\n\
s - summary of results (default)\n\
i - vertices incident to each facet\n\
n - normals with offsets\n\
p - vertex coordinates (if 'Qc', includes coplanar points)\n\
if 'v', Voronoi vertices\n\
Fp - halfspace intersections\n\
Fx - extreme points (convex hull vertices)\n\
FA - compute total area and volume\n\
o - OFF format (if 'v', outputs Voronoi regions)\n\
G - Geomview output (2-d, 3-d and 4-d)\n\
m - Mathematica output (2-d and 3-d)\n\
QVn - print facets that include point n, -n if not\n\
TO file- output results to file, may be enclosed in single quotes\n\
\n\
examples:\n\
- rbox c d D2 | qhull Qc s f Fx | more rbox 1000 s | qhull Tv s FA\n\
+ rbox 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 | qhull n rbox c | qhull FV n | qhull H Fp\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 10 | qhull v QJ o Fv\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) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
main( argc, argv )
processes the command line, calls qhull() to do the work, and exits
design:
initializes data structures
reads points
finishes initialization
computes convex hull and other structures
checks the result
writes the output
frees memory
*/
int main(int argc, char *argv[]) {
int curlong, totlong; /* used !qh_NOmem */
int exitcode, numpoints, dim;
coordT *points;
boolT ismalloc;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
if (!exitcode) {
qh_initflags(qh qhull_command);
points= qh_readpoints(&numpoints, &dim, &ismalloc);
qh_init_B(points, numpoints, dim, ismalloc);
qh_qhull();
qh_check_output();
qh_produce_output();
if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
qh_check_points();
exitcode= qh_ERRnone;
}
qh NOerrexit= True; /* no more setjmp */
#ifdef qh_NOmem
qh_freeqhull( True);
#else
qh_freeqhull( False);
qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qhullr/unix_r.c b/src/qhull/unix_r.c
similarity index 96%
rename from src/qhullr/unix_r.c
rename to src/qhull/unix_r.c
index 2eadbd5..08fea57 100644
--- a/src/qhullr/unix_r.c
+++ b/src/qhull/unix_r.c
@@ -1,366 +1,369 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/qhullr/unix_r.c#5 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/qhull/unix_r.c#5 $$Change: 1951 $
+ $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
*/
-#include "mem_r.h"
-#include "qset_r.h"
-#include "libqhull_r.h"
+#include "libqhull_r/mem_r.h"
+#include "libqhull_r/qset_r.h"
+#include "libqhull_r/libqhull_r.h"
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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 preceeded by a single interior point ('H').\n\
\n\
options:\n\
d - Delaunay triangulation by lifting points to a paraboloid\n\
d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
v - Voronoi diagram (dual of the Delaunay triangulation)\n\
v Qu - furthest-site Voronoi diagram\n\
Hn,n,... - halfspace intersection about point [n,n,0,...]\n\
Qt - triangulated output\n\
QJ - joggled input instead of merged facets\n\
Qc - keep coplanar points with nearest facet\n\
Qi - keep interior points with nearest facet\n\
\n\
Qhull control options:\n\
Qbk:n - scale coord k so that low bound is n\n\
QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
QbB - scale input to unit cube centered at the origin\n\
Qbb - scale last coordinate to [0,m] for Delaunay triangulations\n\
Qbk:0Bk:0 - remove k-th coordinate from input\n\
QJn - randomly joggle input in range [-n,n]\n\
QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
%s%s%s%s"; /* split up qh_prompt for Visual C++ */
char qh_promptb[]= "\
Qf - partition point to furthest outside facet\n\
Qg - only build good facets (needs 'QGn', 'QVn', or 'PdD')\n\
Qm - only process points that would increase max_outside\n\
Qr - process random outside points instead of furthest ones\n\
Qs - search all points for the initial simplex\n\
Qu - for 'd' or 'v', compute upper hull without point at-infinity\n\
returns furthest-site Delaunay triangulation\n\
Qv - test vertex neighbors for convexity\n\
Qx - exact pre-merges (skips coplanar and angle-coplanar facets)\n\
Qz - add point-at-infinity to Delaunay triangulation\n\
QGn - good facet if visible from point n, -n for not visible\n\
QVn - good facet if it includes point n, -n if not\n\
Q0 - turn off default premerge with 'C-0'/'Qx'\n\
Q1 - sort merges by type instead of angle\n\
Q2 - merge all non-convex at once instead of independent sets\n\
Q3 - do not merge redundant vertices\n\
Q4 - avoid old->new merges\n\
Q5 - do not correct outer planes at end of qhull\n\
Q6 - do not pre-merge concave or coplanar facets\n\
Q7 - depth-first processing instead of breadth-first\n\
Q8 - do not process near-inside points\n\
Q9 - process furthest of furthest points\n\
Q10 - no special processing for narrow distributions\n\
Q11 - copy normals and recompute centrums for tricoplanar facets\n\
\n\
";
char qh_promptc[]= "\
Topts- Trace options:\n\
T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
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\
\n\
Output options (subset):\n\
s - summary of results (default)\n\
i - vertices incident to each facet\n\
n - normals with offsets\n\
p - vertex coordinates (if 'Qc', includes coplanar points)\n\
if 'v', Voronoi vertices\n\
Fp - halfspace intersections\n\
Fx - extreme points (convex hull vertices)\n\
FA - compute total area and volume\n\
o - OFF format (if 'v', outputs Voronoi regions)\n\
G - Geomview output (2-d, 3-d and 4-d)\n\
m - Mathematica output (2-d and 3-d)\n\
QVn - print facets that include point n, -n if not\n\
TO file- output results to file, may be enclosed in single quotes\n\
\n\
examples:\n\
- rbox c d D2 | qhull Qc s f Fx | more rbox 1000 s | qhull Tv s FA\n\
+ rbox 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 | qhull n rbox c | qhull FV n | qhull H Fp\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 10 | qhull v QJ o Fv\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) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
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
+
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
qh_init_A(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, True);
#else
qh_freeqhull(qh, False);
qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qhullptest/Coordinates_test.cpp b/src/qhullptest/Coordinates_test.cpp
deleted file mode 100644
index dc31a8f..0000000
--- a/src/qhullptest/Coordinates_test.cpp
+++ /dev/null
@@ -1,534 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/Coordinates_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "Coordinates.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "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
-
-#//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();
-}
-
-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<coordT> 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<coordT> vc= c.toStdVector();
- QCOMPARE(vc.size(), c.size());
- for(size_t k= vc.size(); k--; ){
- QCOMPARE(vc[k], c[k]);
- }
- QList<coordT> qc= c.toQList();
- QCOMPARE(qc.count(), c.count());
- for(int k= qc.count(); k--; ){
- QCOMPARE(qc[k], c[k]);
- }
- Coordinates c4;
- c4= std::vector<double>(2, 0.0);
- QCOMPARE(c4.back(), 0.0);
- Coordinates c5(std::vector<double>(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.empty());
- QVERIFY(c.isEmpty());
- c << 1.0 << -2.0;
- QCOMPARE(c.size(), 2u);
- QCOMPARE(c.count(), 2);
- QVERIFY(!c.empty());
- 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.end());
- 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.end());
- 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);
- 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/qhullptest/DEPRECATED.txt b/src/qhullptest/DEPRECATED.txt
deleted file mode 100644
index db9d81b..0000000
--- a/src/qhullptest/DEPRECATED.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-
-qhull/src/qhullptest
-
- This directory tests the deprecated cpp classes based on libqhullp.
-
- It will be maintained until January 2015.
-
- See qhull/src/qhulltest for the new cpp tests.
-
-
diff --git a/src/qhullptest/PointCoordinates_test.cpp b/src/qhullptest/PointCoordinates_test.cpp
deleted file mode 100644
index 03c6ba6..0000000
--- a/src/qhullptest/PointCoordinates_test.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/PointCoordinates_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "PointCoordinates.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "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
-
-#//Test slots
-private slots:
- void t_construct();
- 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();
-}
-
-void PointCoordinates_test::
-t_construct()
-{
- PointCoordinates pc;
- QCOMPARE(pc.size(), 0U);
- QCOMPARE(pc.coordinateCount(), 0);
- QCOMPARE(pc.dimension(), 0);
- QCOMPARE(pc.coordinates(), (coordT *)0);
- QVERIFY(pc.isEmpty());
- pc.checkValid();
- PointCoordinates pc7(2);
- QCOMPARE(pc7.dimension(), 2);
- QCOMPARE(pc7.count(), 0);
- QVERIFY(pc7.isEmpty());
- QVERIFY(pc7.comment().empty());
- pc7.checkValid();
- PointCoordinates pc2("Test pc2");
- QCOMPARE(pc2.count(), 0);
- QVERIFY(pc2.isEmpty());
- QCOMPARE(pc2.comment(), std::string("Test pc2"));
- pc2.checkValid();
- PointCoordinates pc3(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(2, "Test 2-d pc4", 6, c);
- QCOMPARE(pc4.dimension(), 2);
- QCOMPARE(pc4.count(), 3);
- QCOMPARE(pc4.size(), 3u);
- QVERIFY(!pc4.isEmpty());
- QVERIFY(!pc4.empty());
- 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(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<coordT> 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(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;
- pc6= pc8;
- QVERIFY(pc6!=pc5);
- QVERIFY(pc6.isEmpty());
-}//t_construct
-
-void PointCoordinates_test::
-t_convert()
-{
- //defineAs tested above
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- PointCoordinates ps(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<coordT> vs= ps.toStdVector();
- QCOMPARE(vs.size(), 6u);
- QCOMPARE(vs[5], 5.0);
- QList<coordT> 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
- PointCoordinates pc("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()
-{
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- PointCoordinates pc(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()
-{
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- PointCoordinates pc(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(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()
-{
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- PointCoordinates pc(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()
-{
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- PointCoordinates pc(2, "2-d points", 6, c);
- coordT c3[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- PointCoordinates pc5(2);
- pc5.append(6, c3); // 0-5
- QVERIFY(pc5==pc);
- PointCoordinates pc2(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()
-{
- PointCoordinates pc(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()
-{
- PointCoordinates c(2);
- 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(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;
- 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()
-{
- PointCoordinates c;
- c << 1.0 << 2.0 << 3.0 << 1.0 << 2.0 << 3.0;
- ostringstream os;
- os << "PointCoordinates 0-d\n" << c;
- c.setDimension(2);
- os << "PointCoordinates 1-3-2\n" << c;
- cout << os.str();
- QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count("0"), 3);
- QCOMPARE(s.count("2"), 4);
-}//t_io
-
-}//orgQhull
-
-#include "moc/PointCoordinates_test.moc"
diff --git a/src/qhullptest/Point_test.cpp b/src/qhullptest/Point_test.cpp
deleted file mode 100644
index ab3d1b7..0000000
--- a/src/qhullptest/Point_test.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/Point_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include <iostream>
-using std::cout;
-using std::endl;
-#include "RoadTest.h" // QT_VERSION
-
-#include "QhullPoint.h"
-
-#include "Qhull.h"
-
-namespace orgQhull {
-
-class Point_test : public RoadTest
-{
- Q_OBJECT
-
-#//Test slots
-private slots:
- void initTestCase();
- void t_construct();
- void t_getset();
- void t_operator();
- void t_const_iterator();
- void t_iterator();
- void t_point_iterator();
- // void t_mutable_point_iterator();
- // void t_io();
-};//Point_test
-
-void
-add_Point_test()
-{
- new Point_test();
-}
-
-void Point_test::
-initTestCase(){
- RboxPoints rcube("c");
- Qhull q(rcube, "");
- UsingQhullLib::setGlobals();
-}//initTestCase
-
-void Point_test::
-t_construct()
-{
- QhullPoint p;
- QCOMPARE(p.dimension(), 0);
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoint p2;
- p2.defineAs(3, c);
- QCOMPARE(p2.dimension(), 3);
- QCOMPARE(p2.coordinates(), c);
- coordT c2[]= {0.0, 1.0, 2.0};
- QhullPoint p3(3, c2);
- QVERIFY(p3==p2);
- QhullPoint p5(p3);
- QVERIFY(p5==p3);
-}//t_construct
-
-void Point_test::
-t_getset()
-{
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoint p(3, c);
- QCOMPARE(p.coordinates(), c);
- QCOMPARE(p.dimension(), 3);
- QCOMPARE(p[2], 2.0);
- QhullPoint p2(p);
- p2.defineAs(p);
- QVERIFY(p2==p);
- QVERIFY(p2.coordinates()==p.coordinates());
- QVERIFY(p2.dimension()==p.dimension());
- p2.setDimension(2);
- QCOMPARE(p2.dimension(), 2);
- QVERIFY(p2!=p);
- coordT c2[]= {0.0, 1.0};
- p2.setCoordinates(c2);
- QCOMPARE(p2.coordinates(), c2);
- p.defineAs(2, c);
- QVERIFY(p2==p);
- QCOMPARE(p[1], 1.0);
-}//t_getset
-
-void Point_test::
-t_operator()
-{
- QhullPoint p;
- QhullPoint p2(p);
- QVERIFY(p==p2);
- QVERIFY(!(p!=p2));
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoint p3(3, c);
- QVERIFY(p3!=p2);
- QhullPoint p4(p3);
- QVERIFY(p4==p3);
- coordT c5[]= {5.0, 6.0, 7.0};
- QhullPoint p5(3, c5);
- QVERIFY(p5!=p3);
- QCOMPARE(p5[1], 6.0);
- QCOMPARE(p5[0], 5.0);
- const coordT *c0= &p5[0];
- QCOMPARE(*c0, 5.0);
-}//t_operator
-
-void Point_test::
-t_const_iterator()
-{
- coordT c[]= {1.0, 2.0, 3.0};
- QhullPoint p(3, c);
- QhullPoint::const_iterator i(p.coordinates());
- QhullPoint::const_iterator i2= p.coordinates();
- QVERIFY(i==i2);
- QVERIFY(i>=i2);
- QVERIFY(i<=i2);
- QCOMPARE(*i, 1.0);
- QCOMPARE(*(i+1), 2.0);
- QCOMPARE(*(i+1), i[1]);
- i= p.end();
- QVERIFY(i!=i2);
- i= i2;
- QVERIFY(i==i2);
- i= p.end();
- i= p.begin();
- QCOMPARE(*i, 1.0);
- QhullPoint::ConstIterator i3= p.end();
- QCOMPARE(*(i3-1), 3.0);
- QCOMPARE(*(i3-1), i3[-1]);
- QVERIFY(i!=i3);
- QVERIFY(i<i3);
- QVERIFY(i<=i3);
- QVERIFY(i3>i);
- QVERIFY(i3>=i);
-}//t_const_iterator
-
-
-void Point_test::
-t_iterator()
-{
- coordT c[]= {1.0, 2.0, 3.0};
- QhullPoint p(3, c);
- QhullPoint::Iterator i(p.coordinates());
- QhullPoint::iterator i2= p.coordinates();
- QVERIFY(i==i2);
- QVERIFY(i>=i2);
- QVERIFY(i<=i2);
- QCOMPARE(*i, 1.0);
- QCOMPARE(*(i+1), 2.0);
- QCOMPARE(*(i+1), i[1]);
- i= p.end();
- QVERIFY(i!=i2);
- i= i2;
- QVERIFY(i==i2);
- i= p.end();
- i= p.begin();
- QCOMPARE(*i, 1.0);
- QhullPoint::Iterator i3= p.end();
- QCOMPARE(*(i3-1), 3.0);
- QCOMPARE(*(i3-1), i3[-1]);
- QVERIFY(i!=i3);
- QVERIFY(i<i3);
- QVERIFY(i<=i3);
- QVERIFY(i3>i);
- QVERIFY(i3>=i);
- // compiler errors -- QhullPoint is const-only
- // QCOMPARE((i[0]= -10.0), -10.0);
- // coordT *c3= &i3[1];
-}//t_iterator
-
-void Point_test::
-t_point_iterator()
-{
- coordT c[]= {1.0, 3.0, 4.0};
- QhullPoint p(3, c);
- QhullPointIterator i(p);
- QhullPointIterator i2= p;
- 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());
-
- coordT c2[]= {1.0, 3.0, 4.0};
- QhullPoint p2(0, c2); // 0-dimensional
- i2= p2;
- QVERIFY(!i2.hasNext());
- QVERIFY(!i2.hasPrevious());
- i2.toBack();
- QVERIFY(!i2.hasNext());
- QVERIFY(!i2.hasPrevious());
- QCOMPARE(i.peekPrevious(), 4.0);
- QCOMPARE(i.previous(), 4.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);
- QCOMPARE(i.next(), 4.0);
- QVERIFY(!i.hasNext());
- i.toFront();
- QCOMPARE(i.next(), 1.0);
-}//t_point_iterator
-
-// No MutableQhullPointIterator since QhullPoint is const-only
-
-#if 0
-
-void Point_test::
-t_io()
-{
- QhullPoint p;
- cout<< "INFO: empty point" << p << endl;
- const coordT c[]= {1.0, 3.0, 4.0};
- QhullPoint p2(2, c); // 2-dimensional
- cout<< "INFO: " << p2 << endl;
-}//t_io
-
-error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class orgQhull::QhullPoint &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVPoint@orgQhull@@@Z) referenced in function "private: void __thiscall orgQhull::Point_test::t_io(void)" (?t_io@Point_test@orgQhull@@AAEXXZ)
-
-#endif
-
-}//orgQhull
-
-#include "moc/Point_test.moc"
diff --git a/src/qhullptest/QhullFacetList_test.cpp b/src/qhullptest/QhullFacetList_test.cpp
deleted file mode 100644
index 39f7bcb..0000000
--- a/src/qhullptest/QhullFacetList_test.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullFacetList_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "QhullFacetList.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "QhullVertexSet.h"
-#include "Qhull.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
-
-#//Test slots
-private slots:
- void cleanup();
- void t_construct();
- void t_convert();
- void t_readonly();
- void t_foreach();
- void t_io();
-};//QhullFacetList_test
-
-void
-add_QhullFacetList_test()
-{
- new QhullFacetList_test();
-}
-
-//Executed after each testcase
-void QhullFacetList_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullFacetList_test::
-t_construct()
-{
- 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<QhullFacet> fv= fs2.toStdVector();
- QCOMPARE(fv.size(), 6u);
-}//t_construct
-
-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<QhullFacet> fv= fs2.toStdVector();
- QCOMPARE(fv.size(), 3u);
- QList<QhullFacet> fv2= fs2.toQList();
- QCOMPARE(fv2.size(), 3);
- std::vector<QhullVertex> fv5= fs2.vertices_toStdVector(q.runId());
- QCOMPARE(fv5.size(), 7u);
- QList<QhullVertex> fv6= fs2.vertices_toQList(q.runId());
- QCOMPARE(fv6.size(), 7);
- fs2.selectAll();
- QVERIFY(fs2.isSelectAll());
- std::vector<QhullFacet> fv3= fs2.toStdVector();
- QCOMPARE(fv3.size(), 6u);
- QList<QhullFacet> fv4= fs2.toQList();
- QCOMPARE(fv4.size(), 6);
- std::vector<QhullVertex> fv7= fs2.vertices_toStdVector(q.runId());
- QCOMPARE(fv7.size(), 8u);
- QList<QhullVertex> fv8= fs2.vertices_toQList(q.runId());
- 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(q.runId()); // Runs all print options
- os << "\nFacets only\n" << fs; // printVertices() requires a runId
- cout << os.str();
- QString facets= QString::fromStdString(os.str());
- QCOMPARE(facets.count("(v"), 7+12*3*2);
- QCOMPARE(facets.count(QRegExp("f\\d")), 3*7 + 13*3*2);
- }
-}//t_io
-
-}//orgQhull
-
-#include "moc/QhullFacetList_test.moc"
diff --git a/src/qhullptest/QhullFacetSet_test.cpp b/src/qhullptest/QhullFacetSet_test.cpp
deleted file mode 100644
index bdf421f..0000000
--- a/src/qhullptest/QhullFacetSet_test.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullFacetSet_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h"
-
-#include "QhullFacetSet.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "Qhull.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
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullFacetSet_test::
-cleanup()
-{
- RoadTest::cleanup();
- UsingLibQhull::checkQhullMemoryEmpty();
-}
-
-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.qhullQh()->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<QhullFacet> fv= fs2.toStdVector();
- QCOMPARE(fv.size(), 2u);
- QList<QhullFacet> fv2= fs2.toQList();
- QCOMPARE(fv2.size(), 2);
- fs2.selectAll();
- QVERIFY(fs2.isSelectAll());
- std::vector<QhullFacet> fv3= fs2.toStdVector();
- QCOMPARE(fv3.size(), 4u);
- QList<QhullFacet> 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)){
- 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(q.runId(), "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/qhullptest/QhullFacet_test.cpp b/src/qhullptest/QhullFacet_test.cpp
deleted file mode 100644
index 4305318..0000000
--- a/src/qhullptest/QhullFacet_test.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullFacet_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h"
-
-#include "QhullFacet.h"
-#include "QhullError.h"
-#include "Coordinates.h"
-#include "RboxPoints.h"
-#include "QhullFacetList.h"
-#include "QhullFacetSet.h"
-#include "QhullPointSet.h"
-#include "QhullRidge.h"
-#include "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
-
-#//Test slots
-private slots:
- void cleanup();
- void t_constructConvert();
- void t_getSet();
- void t_value();
- void t_foreach();
- void t_io();
-};//QhullFacet_test
-
-void
-add_QhullFacet_test()
-{
- new QhullFacet_test();
-}
-
-//Executed after each testcase
-void QhullFacet_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullFacet_test::
-t_constructConvert()
-{
- // Qhull.runQhull() constructs QhullFacets as facetT
- QhullFacet f;
- QVERIFY(!f.isDefined());
- 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.isDefined());
- QCOMPARE(f.dimension(),3);
- QhullFacet f5= f2;
- QVERIFY(f5==f2);
- QVERIFY(f5==f);
- QhullFacet f3= f2.getFacetT();
- QCOMPARE(f,f3);
- QhullFacet f4= 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
- 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.isDefined());
- if(i.hasNext()){
- QCOMPARE(f.next(), i.peekNext());
- QVERIFY(f.next()!=f);
- }
- QVERIFY(i.hasPrevious());
- QCOMPARE(f, i.peekPrevious());
- }
- QhullFacetListIterator i2(i);
- QEXPECT_FAIL("", "ListIterator copy constructor not reset to BOT", Continue);
- QVERIFY(!i2.hasPrevious());
-
- // 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 << endl;
- QCOMPARE(h.count(), 3);
- QCOMPARE(h.offset(), -0.5);
- double n= h.norm();
- QCOMPARE(n, 1.0);
- QhullHyperplane hi= f.innerplane(q.runId());
- QCOMPARE(hi.count(), 3);
- double innerOffset= hi.offset()+0.5;
- cout << "InnerPlane: " << hi << "innerOffset+0.5 " << innerOffset << endl;
- QVERIFY(innerOffset >= 0.0);
- QhullHyperplane ho= f.outerplane(q.runId());
- QCOMPARE(ho.count(), 3);
- double outerOffset= ho.offset()+0.5;
- cout << "OuterPlane: " << ho << "outerOffset+0.5 " << outerOffset << endl;
- QVERIFY(outerOffset <= 0.0);
- 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(q.runId());
- cout << "Center: " << center << endl;
- double d= f.distance(center);
- QVERIFY(d < innerOffset-outerOffset);
- QhullPoint center2= f.getCenter(q.runId(), qh_PRINTcentrums);
- QCOMPARE(center, center2);
- if(f.tricoplanarOwner()==tricoplanarOwner){
- tricoplanarCount2++;
- }
- }
- QCOMPARE(tricoplanarCount2, 2);
- Qhull q2(rcube,"d Qz Qt QR0"); // 3-d triangulation of Delaunay triangulation (the cube)
- QhullFacet f2= q2.firstFacet();
- QhullPoint center3= f2.getCenter(q.runId(), qh_PRINTtriangles);
- QCOMPARE(center3.dimension(), 3);
- QhullPoint center4= f2.getCenter(q.runId());
- QCOMPARE(center4.dimension(), 3);
- 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)
-
- UsingLibQhull::setGlobalDistanceEpsilon(1e-12); // Voronoi vertices are not necessarily within distance episilon
- foreach(QhullFacet f, q3.facetList()){ //Qt only
- if(f.isGood()){
- QhullPoint p= f.voronoiVertex(q3.runId());
- cout << p.print(q3.runId(), "Voronoi vertex: ")
- << " DistanceEpsilon " << UsingLibQhull::globalDistanceEpsilon() << endl;
- QCOMPARE(p, q3.origin());
- }
- }
- }
-}//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(q.runId());
- 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.printHeader(q.runId());
- os << f.printFlags(" - flags:");
- os << f.printCenter(q.runId(), qh_PRINTfacets, " - center:");
- os << f.printRidges(q.runId());
- cout << os.str();
- ostringstream os2;
- os2 << f.print(q.runId()); // invokes print*()
- QString facetString2= QString::fromStdString(os2.str());
- facetString2.replace(QRegExp("\\s\\s+"), " ");
- ostringstream os3;
- q.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/qhullptest/QhullHyperplane_test.cpp b/src/qhullptest/QhullHyperplane_test.cpp
deleted file mode 100644
index 6d3d2a3..0000000
--- a/src/qhullptest/QhullHyperplane_test.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullHyperplane_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include <vector>
-#include "RoadTest.h"
-
-#include "QhullHyperplane.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "Qhull.h"
-#include <numeric>
-
-using std::cout;
-using std::endl;
-using std::ostringstream;
-using std::ostream;
-using std::string;
-
-namespace orgQhull {
-
-class QhullHyperplane_test : public RoadTest
-{
- Q_OBJECT
-
-#//Test slots
-private slots:
- void cleanup();
- void t_construct();
- 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();
-}
-
-//Executed after each testcase
-void QhullHyperplane_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullHyperplane_test::
-t_construct()
-{
- // Qhull.runQhull() constructs QhullFacets as facetT
- QhullHyperplane h;
- QVERIFY(!h.isDefined());
- QCOMPARE(h.dimension(),0);
- QCOMPARE(h.coordinates(),static_cast<double *>(0));
- RboxPoints rcube("c");
- Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
- QhullFacet f= q.firstFacet();
- QhullHyperplane h2(f.hyperplane());
- QVERIFY(h2.isDefined());
- QCOMPARE(h2.dimension(),3);
- // h= h2; // copy assignment disabled, ambiguous
- QhullHyperplane h3(h2.dimension(), h2.coordinates(), h2.offset());
- QCOMPARE(h2, h3);
- QhullHyperplane h5= h2; // copy constructor
- QVERIFY(h5==h2);
-}//t_construct
-
-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<double> 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<double> 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.isDefined());
- 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
- const QhullHyperplane h= q.firstFacet().hyperplane();
- double dist= h.distance(q.origin());
- QCOMPARE(dist, -1.0);
- double norm= h.norm();
- QCOMPARE(norm, 1.0);
-}//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");
- {
- QhullHyperplane h2;
- QCOMPARE(h2.begin(), h2.end());
- QCOMPARE(h2.count(), 0);
- QCOMPARE(h2.size(), 0u);
- 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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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(i4<i2);
- QVERIFY(i4<=i2);
- ++i4;
- QVERIFY(i<i4);
- QVERIFY(i<=i4);
- QVERIFY(i4>i);
- 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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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()
-{
- QhullHyperplane h2;
- QhullHyperplaneIterator i= h2;
- QCOMPARE(h2.dimension(), 0);
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
- i.toBack();
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
-
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullHyperplane h = q.firstFacet().hyperplane();
- QhullHyperplaneIterator i2(h);
- QCOMPARE(h.dimension(), 3);
- 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 << "Hyperplane w/ runId:\n";
- os << h.print();
- 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/qhullptest/QhullLinkedList_test.cpp b/src/qhullptest/QhullLinkedList_test.cpp
deleted file mode 100644
index b84c369..0000000
--- a/src/qhullptest/QhullLinkedList_test.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullLinkedList_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <QtCore/QList>
-#include "RoadTest.h"
-
-#include "QhullLinkedList.h"
-#include "Qhull.h"
-
-namespace orgQhull {
-
-class QhullLinkedList_test : public RoadTest
-{
- Q_OBJECT
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullLinkedList_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- 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(!vs2.empty());
- 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());
- QVERIFY(!vs.empty());
- std::vector<QhullVertex> 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<QhullVertex> vs3= vs.toQList();
- QCOMPARE(vs3.count(), vs.count());
- i= vs.begin();
- for(int k= 0; k<vs3.count(); k++){
- QCOMPARE(vs3[k], *i++);
- }
- QhullVertexList vs4(q.endVertex(), q.endVertex());
- QVERIFY(vs4.isEmpty());
- QVERIFY(vs==vs);
- QVERIFY(vs4==vs4);
- QVERIFY(vs!=vs4);
- }
-}//t_convert
-
-//ReadOnly tested by t_convert
-
-void QhullLinkedList_test::
-t_element()
-{
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullVertexList vs = q.vertexList();
- QhullVertex v= vs.first();
- QCOMPARE(v.previous(), QhullVertex(NULL));
- QCOMPARE(vs.front(), vs.first());
- QhullVertex v2= vs.last();
- QCOMPARE(v2.next().next(), QhullVertex(NULL)); // sentinel has NULL next
- QCOMPARE(vs.back(), vs.last());
-}//t_element
-
-void QhullLinkedList_test::
-t_search()
-{
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullVertexList vs = q.vertexList();
- QhullVertex v;
- QVERIFY(!vs.contains(v));
- QCOMPARE(vs.count(v), 0);
- QhullVertex v2= *vs.begin();
- QhullVertex v3= vs.last();
- QVERIFY(vs.contains(v2));
- QCOMPARE(vs.count(v2), 1);
- QVERIFY(vs.contains(v3));
- QCOMPARE(vs.count(v3), 1);
-}//t_search
-
-void QhullLinkedList_test::
-t_iterator()
-{
- RboxPoints rcube("c");
- {
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullVertexList vs = q.vertexList();
- QhullVertexList::Iterator i= vs.begin();
- QhullVertexList::iterator i2= vs.begin();
- QVERIFY(i==i2);
- // No comparisons
- i= vs.begin();
- QVERIFY(i==i2);
- i2= vs.end();
- QVERIFY(i!=i2);
- QhullVertex v3(*i);
- i2--;
- QhullVertex v8= *i2;
- QhullVertex v= vs.first();
- QhullVertex v2= v.next();
- QCOMPARE(v3.id(), v.id());
- QCOMPARE(v8.id(), vs.last().id());
- QhullVertexList::Iterator i3(i2);
- QCOMPARE(*i2, *i3);
-
- (i3= i)++;
- QCOMPARE((*i3).id(), v2.id());
- QVERIFY(i==i);
- QVERIFY(i!=i2);
-
- QhullVertexList::ConstIterator i4= vs.begin();
- QVERIFY(i==i4); // iterator COMP const_iterator
- QVERIFY(i4==i); // const_iterator COMP iterator
- QVERIFY(i2!=i4);
- QVERIFY(i4!=i2);
- ++i4;
-
- i= vs.begin();
- i2= vs.begin();
- QCOMPARE(i, i2++);
- QCOMPARE(*i2, v2);
- QCOMPARE(++i, i2);
- QCOMPARE(i, i2--);
- QCOMPARE(i2, vs.begin());
- QCOMPARE(--i, i2);
- QCOMPARE(i2 += 8, vs.end());
- QCOMPARE(i2 -= 8, vs.begin());
- QCOMPARE(i2+0, vs.begin());
- QCOMPARE(i2+8, vs.end());
- i2 += 8;
- i= i2-0;
- QCOMPARE(i, i2);
- i= i2-8;
- QCOMPARE(i, vs.begin());
-
- //vs.begin end tested above
-
- // QhullVertexList is const-only
- }
-}//t_iterator
-
-void QhullLinkedList_test::
-t_const_iterator()
-{
- RboxPoints rcube("c");
- {
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullVertexList vs = q.vertexList();
- QhullVertexList::ConstIterator i= vs.begin();
- QhullVertexList::const_iterator i2= vs.begin();
- QVERIFY(i==i2);
- i= vs.begin();
- QVERIFY(i==i2);
- i2= vs.end();
- QVERIFY(i!=i2);
- QhullVertex v3(*i);
- i2--;
- QhullVertex v8= *i2;
- QhullVertex v= vs.first();
- QhullVertex v2= v.next();
- QCOMPARE(v3.id(), v.id());
- QCOMPARE(v8.id(), vs.last().id());
- QhullVertexList::ConstIterator i3(i2);
- QCOMPARE(*i2, *i3);
-
- (i3= i)++;
- QCOMPARE((*i3).id(), v2.id());
- QVERIFY(i==i);
- QVERIFY(i!=i2);
-
- // See t_iterator for const_iterator COMP iterator
-
- i= vs.begin();
- i2= vs.constBegin();
- QCOMPARE(i, i2++);
- QCOMPARE(*i2, v2);
- QCOMPARE(++i, i2);
- QCOMPARE(i, i2--);
- QCOMPARE(i2, vs.constBegin());
- QCOMPARE(--i, i2);
- QCOMPARE(i2 += 8, vs.constEnd());
- QCOMPARE(i2 -= 8, vs.constBegin());
- QCOMPARE(i2+0, vs.constBegin());
- QCOMPARE(i2+8, vs.constEnd());
- i2 += 8;
- i= i2-0;
- QCOMPARE(i, i2);
- i= i2-8;
- QCOMPARE(i, vs.constBegin());
-
- // QhullVertexList is const-only
- }
-}//t_const_iterator
-
-void QhullLinkedList_test::
-t_QhullLinkedList_iterator()
-{
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullVertexList vs(q.endVertex(), q.endVertex());
- QhullVertexListIterator i= vs;
- QCOMPARE(vs.count(), 0);
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
- i.toBack();
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
-
- QhullVertexList vs2 = q.vertexList();
- QhullVertexListIterator i2(vs2);
- QCOMPARE(vs2.count(), 8);
- i= vs2;
- 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
- QhullVertexList vs3 = q.vertexList(); // same as vs2
- QhullVertex v3(vs3.first());
- QhullVertex v4= vs3.first();
- QCOMPARE(v3, v4);
- QVERIFY(v3==v4);
- QhullVertex v5(v4.next());
- QVERIFY(v4!=v5);
- QhullVertex v6(v5.next());
- QhullVertex v7(v6.next());
- QhullVertex v8(vs3.last());
- QCOMPARE(i2.peekPrevious(), v8);
- i2.previous();
- i2.previous();
- i2.previous();
- i2.previous();
- QCOMPARE(i2.previous(), v7);
- QCOMPARE(i2.previous(), v6);
- QCOMPARE(i2.previous(), v5);
- QCOMPARE(i2.previous(), v4);
- QVERIFY(!i2.hasPrevious());
- QCOMPARE(i.peekNext(), v4);
- // i.peekNext()= 1.0; // compiler error
- QCOMPARE(i.next(), v4);
- QCOMPARE(i.peekNext(), v5);
- QCOMPARE(i.next(), v5);
- QCOMPARE(i.next(), v6);
- QCOMPARE(i.next(), v7);
- i.next();
- i.next();
- i.next();
- QCOMPARE(i.next(), v8);
- QVERIFY(!i.hasNext());
- i.toFront();
- QCOMPARE(i.next(), v4);
-}//t_QhullLinkedList_iterator
-
-void QhullLinkedList_test::
-t_io()
-{
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // rotated unit cube
- QhullVertexList vs(q.endVertex(), q.endVertex());
- std::cout << "INFO: empty QhullVertextList" << vs << std::endl;
- QhullVertexList vs2= q.vertexList();
- std::cout << "INFO: " << vs2 << std::endl;
-}//t_io
-
-}//namespace orgQhull
-
-#include "moc/QhullLinkedList_test.moc"
diff --git a/src/qhullptest/QhullPointSet_test.cpp b/src/qhullptest/QhullPointSet_test.cpp
deleted file mode 100644
index f67c902..0000000
--- a/src/qhullptest/QhullPointSet_test.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/****************************************************************************
-**
-** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullPointSet_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled header
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "QhullPointSet.h"
-#include "RboxPoints.h"
-#include "QhullPoint.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "Qhull.h"
-
-using std::cout;
-using std::endl;
-using std::ostringstream;
-
-namespace orgQhull {
-
-class QhullPointSet_test : public RoadTest
-{
- Q_OBJECT
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullPointSet_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullPointSet_test::
-t_construct()
-{
- 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.dimension(), f.getFacetT()->outsideset);
- QCOMPARE(ps.dimension(), 3);
- QVERIFY(ps.isEmpty());
- QVERIFY(ps.empty());
- QCOMPARE(ps.count(), 0);
- QCOMPARE(ps.size(), 0u);
- QhullPointSet ps2(q.dimension(), f.getFacetT()->coplanarset);
- QCOMPARE(ps2.dimension(), 3);
- QVERIFY(!ps2.isEmpty());
- QVERIFY(!ps2.empty());
- coplanarCount += ps2.count();
- QCOMPARE(ps2.count(), (int)ps2.size());
- QhullPointSet ps3(ps2);
- QCOMPARE(ps3.dimension(), 3);
- QVERIFY(!ps3.isEmpty());
- QCOMPARE(ps3.count(), ps2.count());
- QVERIFY(ps3==ps2);
- QVERIFY(ps3!=ps);
- // ps4= ps3; //compiler error
- }
- 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();
- QCOMPARE(ps.dimension(), 3);
- QVERIFY(ps.count()>=1); // Sometimes no coplanar points
- std::vector<QhullPoint> vs= ps.toStdVector();
- QCOMPARE(vs.size(), ps.size());
- QhullPoint p= ps[0];
- QhullPoint p2= vs[0];
- QCOMPARE(p, p2);
- QList<QhullPoint> qs= ps.toQList();
- QCOMPARE(qs.size(), static_cast<int>(ps.size()));
- QhullPoint p3= qs[0];
- QCOMPARE(p3, p);
-}//t_convert
-
-// readonly tested in t_construct
-// dimension, 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.first(), p);
- QCOMPARE(ps.front(), ps.first());
- QCOMPARE(ps.last(), p2);
- QCOMPARE(ps.back(), ps.last());
- QhullPoint p8;
- 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(), ps.dimension());
- QCOMPARE(p, ps[0]);
- i2--;
- QhullPoint p2= *i2;
- QCOMPARE(p2.dimension(), ps.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(i<i3);
- QVERIFY(i<=i3);
- QVERIFY(i3>i);
- 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(i4<i2);
- QVERIFY(i4<=i2);
- ++i4;
- QVERIFY(i<i4);
- QVERIFY(i<=i4);
- QVERIFY(i4>i);
- 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+=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(), ps.dimension());
- QCOMPARE(p, ps[0]);
- i2--;
- QhullPoint p2= *i2;
- QCOMPARE(p2.dimension(), ps.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(i<i3);
- QVERIFY(i<=i3);
- QVERIFY(i3>i);
- 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);
- QhullPoint p4;
- QCOMPARE(ps.indexOf(p), 0);
- QCOMPARE(ps.indexOf(p2), ps.count()-1);
- QCOMPARE(ps.indexOf(p3), 2);
- 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;
- 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;
- 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.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);
- 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 << "\nRunId\n" << ps.print(q.runId());
- os << ps.print(q.runId(), "\nRunId w/ message\n");
- cout << os.str();
- QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count("p"), 3*ps.count()+1);
- // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
-}//t_io
-
-}//orgQhull
-
-#include "moc/QhullPointSet_test.moc"
diff --git a/src/qhullptest/QhullPoint_test.cpp b/src/qhullptest/QhullPoint_test.cpp
deleted file mode 100644
index d7aa94d..0000000
--- a/src/qhullptest/QhullPoint_test.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullPoint_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h"
-
-#include "QhullPoint.h"
-#include "Coordinates.h"
-#include "RboxPoints.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "QhullPoint.h"
-#include "Qhull.h"
-
-#include <numeric>
-
-using std::cout;
-using std::endl;
-using std::ostringstream;
-using std::ostream;
-using std::string;
-
-namespace orgQhull {
-
-class QhullPoint_test : public RoadTest
-{
- Q_OBJECT
-
-#//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_io();
-};//QhullPoint_test
-
-void
-add_QhullPoint_test()
-{
- new QhullPoint_test();
-}
-
-//Executed after each test
-void QhullPoint_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullPoint_test::
-t_construct()
-{
- // Qhull.runQhull() constructs QhullFacets as facetT
- QhullPoint p;
- QVERIFY(!p.isDefined());
- QCOMPARE(p.dimension(),0);
- QCOMPARE(p.coordinates(),static_cast<double *>(0));
- RboxPoints rcube("c");
- Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
- QhullVertex v2(q.beginVertex());
- QhullPoint p2(v2.point());
- QVERIFY(p2.isDefined());
- QCOMPARE(p2.dimension(),3);
- // p= p2; // copy assignment disabled, ambiguous
- QhullPoint p3(p2.dimension(), p2.coordinates());
- QCOMPARE(p2, p3);
- Coordinates c;
- c << 0.0 << 0.0 << 0.0;
- QhullPoint p6(c);
- QCOMPARE(p6, 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<double> vs= p.toStdVector();
- QCOMPARE(vs.size(), 3u);
- for(int k=3; k--; ){
- QCOMPARE(vs[k], p[k]);
- }
- QList<double> 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();
- QhullVertexListIterator i(vs);
- while(i.hasNext()){
- QhullPoint p= i.next().point();
- int id= p.id(q.runId());
- cout << "p" << id << endl;
- QVERIFY(p.isDefined());
- 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);
- }
- 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;
- 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");
- {
- QhullPoint p2;
- QCOMPARE(p2.begin(), p2.end());
- Qhull q(rcube,"QR0"); // rotated unit cube
- 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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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(i4<i2);
- QVERIFY(i4<=i2);
- ++i4;
- QVERIFY(i<i4);
- QVERIFY(i<=i4);
- QVERIFY(i4>i);
- 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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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()
-{
- QhullPoint p2;
- QhullPointIterator i= p2;
- QCOMPARE(p2.dimension(), 0);
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
- i.toBack();
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
-
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // rotated unit cube
- 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_io()
-{
- RboxPoints rcube("c");
- {
- Qhull q(rcube, "");
- QhullPoint p= q.beginVertex().point();
- ostringstream os;
- os << "Point w/o runId:\n";
- os << p;
- os << "Point w/ runId:\n";
- os << p.print(q.runId()) << p.print(q.runId(), " and a message ");
- os << p.printWithIdentifier(q.runId(), " Point with id and a message ");
- cout << os.str();
- QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count("p"), 3);
- // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
- }
-}//t_io
-
-}//orgQhull
-
-#include "moc/QhullPoint_test.moc"
diff --git a/src/qhullptest/QhullPoints_test.cpp b/src/qhullptest/QhullPoints_test.cpp
deleted file mode 100644
index 4591c06..0000000
--- a/src/qhullptest/QhullPoints_test.cpp
+++ /dev/null
@@ -1,481 +0,0 @@
-/****************************************************************************
-**
-** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullPoints_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled header
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "QhullPoints.h"
-#include "RboxPoints.h"
-#include "Qhull.h"
-
-using std::cout;
-using std::endl;
-using std::ostringstream;
-
-namespace orgQhull {
-
-class QhullPoints_test : public RoadTest
-{
- Q_OBJECT
-
-#//Test slots
-private slots:
- void cleanup();
- void t_construct();
- 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();
-}
-
-//Executed after each testcase
-void QhullPoints_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullPoints_test::
-t_construct()
-{
- QhullPoints ps;
- QCOMPARE(ps.dimension(), 0);
- QVERIFY(ps.isEmpty());
- QVERIFY(ps.empty());
- 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;
- ps2.defineAs(2, 6, c);
- QCOMPARE(ps2.dimension(), 2);
- QVERIFY(!ps2.isEmpty());
- QVERIFY(!ps2.empty());
- QCOMPARE(ps2.count(), 3);
- QCOMPARE(ps2.size(), 3u);
- QCOMPARE(ps2.coordinates(), c);
- QhullPoints ps7(3);
- QCOMPARE(ps7.dimension(), 3);
- QVERIFY(ps7.isEmpty());
- QhullPoints ps3(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(2, 6, c2);
- QVERIFY(ps6==ps2);
-}//t_construct
-
-void QhullPoints_test::
-t_convert()
-{
- //defineAs tested above
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- QhullPoints ps(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<QhullPoint> vs= ps.toStdVector();
- QCOMPARE(vs.size(), 2u);
- QhullPoint p= vs[1];
- QCOMPARE(p[2], 5.0);
- QList<QhullPoint> qs= ps.toQList();
- QCOMPARE(qs.size(), 2);
- QhullPoint p2= qs[1];
- QCOMPARE(p2[2], 5.0);
-}//t_convert
-
-void QhullPoints_test::
-t_getset()
-{
- //See t_construct for coordinates, count, defineAs, dimension, empty, isempty, ==, !=, size
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- QhullPoints ps(3, 6, c);
- QhullPoints ps2(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(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()
-{
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- QhullPoints ps(2, 6, c);
- QhullPoint p(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());
- QVERIFY(ps3.empty());
- 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;
- 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()
-{
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoints ps(1, 3, c);
- 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(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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- QVERIFY(i2>=i);
-
- QhullPoints::ConstIterator i4(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(i4<i2);
- QVERIFY(i4<=i2);
- ++i4;
- QVERIFY(i<i4);
- QVERIFY(i<=i4);
- QVERIFY(i4>i);
- 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()
-{
- coordT c[]= {0.0, 1.0, 2.0};
- const QhullPoints ps(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(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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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()
-{
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 0, 1};
- QhullPoints ps(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(2, c2); //2-d point
- QVERIFY(ps.contains(p3));
- QhullPoint p4(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(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 ps2(3);
- QCOMPARE(ps2.indexOf(ps2.data()), -1);
- QCOMPARE(ps2.indexOf(ps2.data()+1, QhullError::NOthrow), -1);
- QCOMPARE(ps2.indexOf(p), -1);
- QCOMPARE(ps2.lastIndexOf(p), -1);
- QhullPoints ps3;
- 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(2, 0, c);
- QCOMPARE(ps4.indexOf(p), -1);
- QCOMPARE(ps4.lastIndexOf(p), -1);
-}//t_search
-
-void QhullPoints_test::
-t_points_iterator()
-{
- coordT c2[]= {0.0};
- QhullPoints ps2(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(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()
-{
- QhullPoints ps;
- ostringstream os;
- os << "Empty QhullPoints\n" << ps << endl;
- coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
- QhullPoints ps2(3, 6, c); // 3-dimensional explicit
- os << "QhullPoints from c[]\n" << ps2 << endl;
- RboxPoints rcube("c");
- Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
- QhullPoints ps3= q.points();
- os << "QhullPoints\n" << ps3;
- os << "RunId\n" << ps3.print(q.runId());
- os << ps3.print(q.runId(), "RunId w/ message\n");
- os << ps3.printWithIdentifier(q.runId(), "RunId w/ identifiers\n");
- cout << os.str();
- QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count("p"), 3*8+3);
- // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
-}//t_io
-
-}//orgQhull
-
-#include "moc/QhullPoints_test.moc"
diff --git a/src/qhullptest/QhullRidge_test.cpp b/src/qhullptest/QhullRidge_test.cpp
deleted file mode 100644
index 1fbccd1..0000000
--- a/src/qhullptest/QhullRidge_test.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullRidge_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h"
-
-#include "QhullRidge.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacet.h"
-#include "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
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullRidge_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullRidge_test::
-t_construct()
-{
- // Qhull.runQhull() constructs QhullFacets as facetT
- QhullRidge r;
- QVERIFY(!r.isDefined());
- QCOMPARE(r.dimension(),0);
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0"); // triangulation of rotated unit cube
- 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.isDefined());
- QCOMPARE(r.dimension(), 2);
- QhullRidge r3= r2.getRidgeT();
- QCOMPARE(r,r3);
- QhullRidge r4= 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.isDefined());
- QVERIFY(r==r);
- QVERIFY(r==i.peekPrevious());
- QCOMPARE(r.otherFacet(r.bottomFacet()),r.topFacet());
- QCOMPARE(r.otherFacet(r.topFacet()),r.bottomFacet());
- }
- QhullRidgeSetIterator i2(i);
- QEXPECT_FAIL("", "SetIterator copy constructor not reset to BOT", Continue);
- QVERIFY(!i2.hasPrevious());
- }
-}//t_getSet
-
-void QhullRidge_test::
-t_foreach()
-{
- RboxPoints rcube("c"); // cube
- {
- Qhull q(rcube, "QR0"); // rotated cube
- QhullFacet f(q.firstFacet());
- foreach (QhullRidge r, f.ridges()){ // Qt only
- QhullVertexSet vs= r.vertices();
- QCOMPARE(vs.count(), 2);
- foreach (QhullVertex v, vs){ // Qt only
- QVERIFY(f.vertices().contains(v));
- }
- }
- QhullRidgeSet rs= f.ridges();
- QhullRidge r= rs.first();
- QhullRidge r2= r;
- QList<QhullVertex> vs;
- int count= 0;
- while(!count || r2!=r){
- ++count;
- QhullVertex v;
- 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 Without runId\n" << rs << "Ridge\n" << r;
- os << "Ridge with runId\n" << r.print(q.runId());
- cout << os.str();
- QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count(" r"), 6+2);
- }
-}//t_io
-
-}//orgQhull
-
-#include "moc/QhullRidge_test.moc"
diff --git a/src/qhullptest/QhullSet_test.cpp b/src/qhullptest/QhullSet_test.cpp
deleted file mode 100644
index 9f8e57a..0000000
--- a/src/qhullptest/QhullSet_test.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullSet_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include <QtCore/QList>
-#include "RoadTest.h" // QT_VERSION
-
-#include "QhullRidge.h"
-#include "QhullFacetSet.h"
-#include "Qhull.h"
-
-using std::cout;
-using std::endl;
-
-namespace orgQhull {
-
-class QhullSet_test : public RoadTest
-{
- Q_OBJECT
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullSet_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- 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.qhullQh()->other_points); // Force an empty set
- QVERIFY(fs.isEmpty());
- QVERIFY(fs.empty());
- 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());
- QVERIFY(!rs.empty());
- 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(!fs2.empty());
- 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<QhullRidge> rv= rs.toStdVector();
- QCOMPARE(rv.size(), 4u);
- QList<QhullRidge> rv2= rs.toQList();
- QCOMPARE(rv2.size(), 4);
- std::vector<QhullRidge>::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<QhullFacet> vs= fs.toStdVector();
- QCOMPARE(vs.size(), fs.size());
- for(int k= fs.count(); k--; ){
- QCOMPARE(vs[k], fs[k]);
- }
- QList<QhullFacet> 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());
- QhullFacet *d= fs.data();
- const QhullFacet *d2= fs.data();
- const QhullFacet *d3= fs.constData();
- QVERIFY(d==d2);
- QVERIFY(d2==d3);
- QCOMPARE(*d, fs.first());
- QCOMPARE(d+4, fs.end());
- QCOMPARE((d+4)->getFacetT(), static_cast<facetT *>(0));
- QhullFacet f4= *(d+4);
- QVERIFY(!f4.isDefined());
- 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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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(i4<i2);
- QVERIFY(i4<=i2);
- ++i4;
- QVERIFY(i<i4);
- QVERIFY(i<=i4);
- QVERIFY(i4>i);
- 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(i<i2);
- QVERIFY(i<=i2);
- QVERIFY(i2>i);
- 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.qhullQh()->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.qhullQh()->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/qhullptest/QhullVertexSet_test.cpp b/src/qhullptest/QhullVertexSet_test.cpp
deleted file mode 100644
index e8f950e..0000000
--- a/src/qhullptest/QhullVertexSet_test.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullVertexSet_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include <iostream>
-#include "../road/RoadTest.h" // FIXUP First for QHULL_USES_QT
-
-#include "Qhull.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "QhullFacetSet.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
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullFacetSet_test::
-cleanup()
-{
- RoadTest::cleanup();
- UsingQhullLib::checkQhullMemoryEmpty();
-}
-
-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.qhullQh()->facet_mergeset);
- QVERIFY(fs3.isEmpty());
-}//t_construct
-
-void QhullFacetSet_test::
-t_convert()
-{
- RboxPoints rcube("c");
- Qhull q(rcube,"QR0 QV2"); // rotated unit cube
- QhullFacet f= q.firstFacet();
- QhullFacetSet fs2= f.neighborFacets();
- QVERIFY(!fs2.isSelectAll());
- QCOMPARE(fs2.count(),2);
- std::vector<QhullFacet> fv= fs2.toStdVector();
- QCOMPARE(fv.size(), 2u);
- QList<QhullFacet> fv2= fs2.toQList();
- QCOMPARE(fv2.size(), 2);
- fs2.selectAll();
- QVERIFY(fs2.isSelectAll());
- std::vector<QhullFacet> fv3= fs2.toStdVector();
- QCOMPARE(fv3.size(), 4u);
- QList<QhullFacet> 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)){
- 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(q.runId(), "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
-
-//FIXUP -- Move conditional, QhullFacetSet code to QhullFacetSet.cpp
-#ifndef QHULL_NO_STL
-std::vector<QhullFacet> QhullFacetSet::
-toStdVector() const
-{
- QhullSetIterator<QhullFacet> i(*this);
- std::vector<QhullFacet> vs;
- while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.push_back(f);
- }
- }
- return vs;
-}//toStdVector
-#endif //QHULL_NO_STL
-
-#ifdef QHULL_USES_QT
-QList<QhullFacet> QhullFacetSet::
-toQList() const
-{
- QhullSetIterator<QhullFacet> i(*this);
- QList<QhullFacet> vs;
- while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.append(f);
- }
- }
- return vs;
-}//toQList
-#endif //QHULL_USES_QT
-
-}//orgQhull
-
-#include "moc/QhullFacetSet_test.moc"
diff --git a/src/qhullptest/QhullVertex_test.cpp b/src/qhullptest/QhullVertex_test.cpp
deleted file mode 100644
index 078d872..0000000
--- a/src/qhullptest/QhullVertex_test.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/QhullVertex_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h"
-
-#include "QhullVertex.h"
-#include "Coordinates.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacet.h"
-#include "QhullFacetSet.h"
-#include "QhullVertexSet.h"
-#include "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
-
-#//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();
-}
-
-//Executed after each testcase
-void QhullVertex_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void QhullVertex_test::
-t_constructConvert()
-{
- // Qhull.runQhull() constructs QhullFacets as facetT
- QhullVertex v;
- QVERIFY(!v.isDefined());
- QCOMPARE(v.dimension(),0);
- RboxPoints rcube("c");
- Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
- QhullVertex v2(q.beginVertex());
- QCOMPARE(v2.dimension(),3);
- v= v2; // copy assignment
- QVERIFY(v.isDefined());
- QCOMPARE(v.dimension(),3);
- QhullVertex v5= v2; // copy constructor
- QVERIFY(v5==v2);
- QVERIFY(v5==v);
- QhullVertex v3= v2.getVertexT();
- QCOMPARE(v,v3);
- QhullVertex v4= 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.isDefined());
- if(i.hasNext()){
- QCOMPARE(v.next(), i.peekNext());
- QVERIFY(v.next()!=v);
- QVERIFY(v.next().previous()==v);
- }
- QVERIFY(i.hasPrevious());
- QCOMPARE(v, i.peekPrevious());
- }
- QhullVertexListIterator i2(i);
- QEXPECT_FAIL("", "ListIterator copy constructor not reset to BOT", Continue);
- QVERIFY(!i2.hasPrevious());
-
- // test point()
- foreach (QhullVertex v, q.vertexList()){ // Qt only
- QhullPoint p= v.point();
- int j= p.id(q.runId());
- cout << "Point " << j << ":\n" << p.print(q.runId()) << 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 w/o runId:\n";
- os << v;
- QhullVertexSet vs= q.firstFacet().vertices();
- os << vs;
- os << "Vertex and vertices w/ runId:\n";
- os << v.print(q.runId());
- os << vs.print(q.runId(), "vertices:");
- 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 w/o runId:\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 w/o runId:\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/qhullptest/Qhull_test.cpp b/src/qhullptest/Qhull_test.cpp
deleted file mode 100644
index 69507d8..0000000
--- a/src/qhullptest/Qhull_test.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/Qhull_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "Qhull.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "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
-
-#//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();
-}
-
-//Executed after each testcase
-void Qhull_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void Qhull_test::
-t_construct()
-{
- {
- Qhull q;
- QCOMPARE(q.dimension(),0);
- QVERIFY(q.qhullQh()!=0);
- QVERIFY(q.runId()!=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();
- }
- Qhull q2(q); // Copy constructor and copy assignment OK if not q.initialized()
- QCOMPARE(q2.dimension(),0);
- q= q2;
- QCOMPARE(q.dimension(),0);
- }
- {
- 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);
- try{
- Qhull q2(q);
- QFAIL("Copy constructor did not fail for initialized Qhull.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- try{
- Qhull q3;
- q3= q;
- QFAIL("Copy assignment did not fail for initialized Qhull source.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- QCOMPARE(q.dimension(),3);
- try{
- Qhull q4;
- q= q4;
- QFAIL("Copy assignment did not fail for initialized Qhull destination.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- QCOMPARE(q.dimension(),3);
- }
- {
- 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;
- q.feasiblePoint << 0.0 << 0.0;
- Coordinates c(std::vector<double>(2, 0.0));
- QVERIFY(q.feasiblePoint==c);
- q.setOutputStream(&cout);
- q.runQhull("normals of square", 3, 4, normals, "H"); // halfspace intersect
- QCOMPARE(q.facetList().count(), 4); // Vertices of square
- cout << "Expecting summary of halfspace intersect\n";
- q.outputQhull();
- q.useOutputStream= false;
- 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 QH11026 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::fromAscii(s).left(6), QString("QH6023"));
- }
- //FIXUP QH11026 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::fromAscii(s).left(6), QString("QH6029"));
- }
- //FIXUP QH11026 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);
- QVERIFY(q.runId()!=0);
- q.setErrorStream(&cout);
- q.outputQhull();
- }
- {
- Qhull q;
- q.runQhull(rcube, "");
- q.setOutputStream(&cout);
- q.outputQhull();
- }
- // qhullQh -- UsingLibQhull [Qhull.cpp]
- // runId -- UsingLibQhull [Qhull.cpp]
-}//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.qhullQh()->ALLpoints, 0u);
- QCOMPARE(q.qhullQh()->GOODpoint, 0);
- QCOMPARE(q.qhullQh()->IStracing, 0);
- QCOMPARE(q.qhullQh()->MAXcoplanar+1.0, 1.0); // fuzzy compare
- QCOMPARE(q.qhullQh()->MERGING, 1u);
- QCOMPARE(q.qhullQh()->input_dim, 3);
- QCOMPARE(QString(q.qhullQh()->qhull_options).left(8), QString(" run-id"));
- QCOMPARE(q.qhullQh()->run_id, q.runId());
- QCOMPARE(q.qhullQh()->num_facets, 6);
- QCOMPARE(q.qhullQh()->hasTriangulation, 0u);
- QCOMPARE(q.qhullQh()->max_outside - q.qhullQh()->min_vertex + 1.0, 1.0); // fuzzy compare
- QCOMPARE(*q.qhullQh()->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.c
-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_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/qhullptest/RboxPoints_test.cpp b/src/qhullptest/RboxPoints_test.cpp
deleted file mode 100644
index 161be97..0000000
--- a/src/qhullptest/RboxPoints_test.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2006-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/RboxPoints_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "RboxPoints.h"
-#include "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
-
-#//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();
-}
-
-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);
- 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(2);
- 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<rp.endCoordinates()){
- QVERIFY(++ci<rp.endCoordinates());
- QCOMPARE(*cci, *ci);
- i++;
- }
- QVERIFY(++ci==rp.endCoordinates());
- QCOMPARE(i, 8*3);
- orgQhull::Coordinates::Iterator ci4= rp.beginCoordinates(4);
- QCOMPARE(rp.endCoordinates()-ci4, 4*3);
- orgQhull::Coordinates::ConstIterator cci4= rp.beginCoordinates(4);
- orgQhull::Coordinates::ConstIterator cci5= rp.endCoordinates();
- QCOMPARE(cci5-cci4, 4*3);
-}//t_foreach
-
-void RboxPoints_test::
-t_change()
-{
- RboxPoints rp("c D2");
- stringstream s;
- s << "4 count" << endl;
- s << "2 dimension" << endl;
- s << "1 2 3 4 5 6 7 8" << endl;
- rp.appendPoints(s);
- QCOMPARE(rp.count(), 8);
- orgQhull::Coordinates::Iterator ci= rp.beginCoordinates(7);
- QCOMPARE(*ci, 7.0);
- try{
- stringstream s2;
- s2 << "4 count" << endl;
- s2 << "2 dimension" << endl;
- s2 << "1 2 3 4 5 6 7 " << endl;
- rp.appendPoints(s2);
- QFAIL("incomplete appendPoints() did not fail.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- RboxPoints rp2;
- rp2.append(rp);
- QCOMPARE(rp2.count(), 8);
- orgQhull::Coordinates::ConstIterator cci2= rp2.beginCoordinates(6);
- QCOMPARE(*(cci2+1), 6.0);
- rp2.appendPoints("D2 10 P0");
- QCOMPARE(rp2.count(), 19);
- orgQhull::Coordinates::ConstIterator cie= rp2.beginCoordinates(8);
- QCOMPARE(*cie, 0.0);
- RboxPoints rp3;
- coordT points[] = { 0, 1,1,0,1,1,0,0};
- rp3.setDimension(2);
- rp3.append(8,points);
- QCOMPARE(rp3.count(), 4);
- orgQhull::Coordinates::Iterator ci3= rp3.beginCoordinates(3);
- QCOMPARE(*ci3, 0.0);
-}//t_change
-
-void RboxPoints_test::
-t_ostream()
-{
- RboxPoints rp("c D2");
- ostringstream oss;
- oss << rp;
- string s= oss.str();
- QString qs= QString::fromStdString(s);
- QCOMPARE(qs.count("-0.5"), 4);
-}//t_ostream
-
-}//orgQhull
-
-#include "moc/RboxPoints_test.moc"
diff --git a/src/qhullptest/RoadTest.cpp b/src/qhullptest/RoadTest.cpp
deleted file mode 100644
index 567e379..0000000
--- a/src/qhullptest/RoadTest.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/RoadTest.cpp#2 $$Change: 1810 $
-** $Date: 2015/01/17 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include <stdexcept>
-#include "RoadTest.h"
-
-using std::cout;
-using std::endl;
-
-namespace orgQhull {
-
-#//class variable
-
-QList<RoadTest*> RoadTest::
-s_testcases;
-
-int RoadTest::
-s_test_count= 0;
-
-int RoadTest::
-s_test_fail= 0;
-
-QStringList RoadTest::
-s_failed_tests;
-
-#//Slot
-
-//! Executed after each test
-void RoadTest::
-cleanup()
-{
- s_test_count++;
- if(QTest::currentTestFailed()){
- recordFailedTest();
- }
-}//cleanup
-
-#//Helper
-
-void RoadTest::
-recordFailedTest()
-{
- s_test_fail++;
- QString className= metaObject()->className();
- s_failed_tests << className + "::" + QTest::currentTestFunction();
-}
-
-#//class function
-
-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/qhullptest/RoadTest.h b/src/qhullptest/RoadTest.h
deleted file mode 100644
index fc3a2d4..0000000
--- a/src/qhullptest/RoadTest.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/RoadTest.h#2 $$Change: 1810 $
-** $Date: 2015/01/17 $$Author: bbarber $
-**
-****************************************************************************/
-
-#ifndef ROADTEST_H
-#define ROADTEST_H
-
-//pre-compiled with RoadTest.h
-#include <QObject> // Qt C++ Framework
-#include <QtTest/QtTest>
-
-#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
-#//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();
-}
-
-Send additional output to cout
-*/
-
-class RoadTest : public QObject
-{
- Q_OBJECT
-
-#//!\name Class globals
-protected:
- static QList<RoadTest *>
- 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); }
- ~RoadTest() { s_testcases.removeAll(this); }
-
-#//Helper
- void recordFailedTest();
-
-
-#//!\name Class functions
- 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/qhullptest/UsingLibQhull_test.cpp b/src/qhullptest/UsingLibQhull_test.cpp
deleted file mode 100644
index 4fe94b4..0000000
--- a/src/qhullptest/UsingLibQhull_test.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/UsingLibQhull_test.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "UsingLibQhull.h"
-#include "QhullError.h"
-#include "Qhull.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 UsingLibQhull_test : public RoadTest
-{
- Q_OBJECT
-
-#//Test slots
-private slots:
- void cleanup();
- void t_classMembers();
- void t_globalPoints();
- void t_UsingLibQhull();
- void t_methods();
- void t_cleanuptestcase();
-};//UsingLibQhull_test
-
-void
-add_UsingLibQhull_test()
-{
- new UsingLibQhull_test();
-}
-
-//Executed after each testcase
-void UsingLibQhull_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void UsingLibQhull_test::
-t_classMembers()
-{
- {
- //checkQhullMemoryEmpty tested by cleanup()
- QCOMPARE(UsingLibQhull::globalMachineEpsilon()+1.0, 1.0);
- RboxPoints r10("10");
- Qhull q(r10,"v"); // voronoi diagram of 10 points
- UsingLibQhull::unsetGlobalAngleEpsilon();
- UsingLibQhull::unsetGlobalDistanceEpsilon();
- cout << "MachineEpsilon " << UsingLibQhull::globalMachineEpsilon()
- << " angleEpsilon " << UsingLibQhull::globalAngleEpsilon()
- << " distanceEpsilon " << UsingLibQhull::globalDistanceEpsilon()
- << endl;
- QCOMPARE(UsingLibQhull::currentAngleEpsilon()+1.0, 1.0);
- QVERIFY(UsingLibQhull::currentAngleEpsilon() > UsingLibQhull::globalMachineEpsilon());
- QCOMPARE(UsingLibQhull::currentDistanceEpsilon()+1.0, 1.0);
- QVERIFY(UsingLibQhull::currentDistanceEpsilon() >= UsingLibQhull::currentAngleEpsilon());
- QCOMPARE(UsingLibQhull::currentQhull().runId(), q.runId());
- QCOMPARE(UsingLibQhull::globalAngleEpsilon()+1.0, UsingLibQhull::currentAngleEpsilon()+1.0);
- QCOMPARE(UsingLibQhull::currentVertexDimension(), q.dimension());
- QCOMPARE(UsingLibQhull::globalDistanceEpsilon()+1.0, UsingLibQhull::currentDistanceEpsilon()+1.0);
- UsingLibQhull::setGlobalAngleEpsilon(1.0);
- UsingLibQhull::setGlobalDistanceEpsilon(1.0);
- cout << " Global angleEpsilon " << UsingLibQhull::globalAngleEpsilon()
- << " distanceEpsilon " << UsingLibQhull::globalDistanceEpsilon()
- << endl;
- QCOMPARE(UsingLibQhull::globalAngleEpsilon(), UsingLibQhull::globalDistanceEpsilon());
- QVERIFY(UsingLibQhull::currentAngleEpsilon() != UsingLibQhull::globalAngleEpsilon());
- UsingLibQhull::setGlobalVertexDimension(3);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), UsingLibQhull::currentVertexDimension());
- UsingLibQhull::setGlobalVertexDimension(2);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), 2);
- QCOMPARE(UsingLibQhull::currentVertexDimension(), q.dimension());
- QVERIFY(UsingLibQhull::currentDistanceEpsilon() != UsingLibQhull::globalDistanceEpsilon());
- UsingLibQhull::unsetGlobalAngleEpsilon();
- UsingLibQhull::unsetGlobalVertexDimension();
- UsingLibQhull::unsetGlobalDistanceEpsilon();
- QCOMPARE(UsingLibQhull::currentAngleEpsilon()+1.0, UsingLibQhull::globalAngleEpsilon()+1.0);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), UsingLibQhull::currentVertexDimension());
- QCOMPARE(UsingLibQhull::currentDistanceEpsilon()+1.0, UsingLibQhull::globalDistanceEpsilon()+1.0);
- UsingLibQhull::setGlobals();
- }
- QCOMPARE(UsingLibQhull::globalAngleEpsilon()+1.0, 1.0);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), 4); // 'v'. VertexDimension is only used for QhullVertex where dim>15
- QCOMPARE(UsingLibQhull::globalDistanceEpsilon()+1.0, 1.0);
- UsingLibQhull::unsetGlobals();
- try{
- cout << UsingLibQhull::globalVertexDimension();
- QFAIL("Did not throw error for undefined dimension.");
- }catch(const std::exception &e){
- cout << "INFO Caught error -- " << e.what() << endl;
- }
-}//t_classMembers
-
-void UsingLibQhull_test::
-t_globalPoints()
-{
- const coordT *r10PointsBegin;
- {
- RboxPoints r10("10");
- Qhull q(r10,"v"); // voronoi diagram of 10 points
- UsingLibQhull::unsetGlobalPoints();
- int dimension;
- const coordT *pointsEnd;
- const coordT *pointsBegin= UsingLibQhull::globalPoints(&dimension, &pointsEnd);
- cout << "pointsBegin " << pointsBegin
- << " pointsEnd " << pointsEnd
- << " dimension " << dimension
- << endl;
- int dimension2;
- const coordT *pointsEnd2;
- const coordT *pointsBegin2= UsingLibQhull::currentPoints(&dimension2, &pointsEnd2);
- QCOMPARE(pointsBegin2, pointsBegin);
- QCOMPARE(pointsEnd2, pointsEnd);
- QCOMPARE(dimension2, dimension);
- coordT c[]= { 1.0,2.0, 3.0,4.0, 5.0,6.0 };
- UsingLibQhull::setGlobalPoints(2, c, c+3*2);
- pointsBegin= UsingLibQhull::globalPoints(&dimension, &pointsEnd);
- QCOMPARE(pointsBegin, c);
- QCOMPARE(pointsEnd[-1], 6.0);
- QCOMPARE(dimension, 2);
- UsingLibQhull::unsetGlobalPoints();
- pointsBegin= UsingLibQhull::globalPoints(&dimension, &pointsEnd);
- QCOMPARE(pointsBegin, pointsBegin2);
- QCOMPARE(pointsEnd, pointsEnd2);
- QCOMPARE(dimension, dimension2);
- UsingLibQhull::setGlobals();
- r10PointsBegin= pointsBegin;
- }
- int dimension3;
- const coordT *pointsEnd3;
- const coordT *pointsBegin3= UsingLibQhull::currentPoints(&dimension3, &pointsEnd3);
- QCOMPARE(pointsBegin3, r10PointsBegin); // Memory was freed
- QCOMPARE(pointsEnd3, r10PointsBegin+10*4);
- QCOMPARE(dimension3, 4);
- UsingLibQhull::unsetGlobals();
- try{
- pointsBegin3= UsingLibQhull::globalPoints(&dimension3, &pointsEnd3);
- QFAIL("Did not throw error for undefined global points.");
- }catch(const std::exception &e){
- cout << "INFO Caught error -- " << e.what() << endl;
- }
-}//t_globalPoints
-
-void UsingLibQhull_test::
-t_UsingLibQhull()
-{
- {
- Qhull q;
- UsingLibQhull uq(&q); // Normally created in a method using 'this'
-
- try{
- Qhull q2; // If qh_QHpointer, QhullQh() calls usinlibqhull()
- UsingLibQhull uq2(&q2);
- QFAIL("UsingLibQhull did not fail.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- }
- Qhull q3;
- UsingLibQhull uq3(&q3);
- // UsingLibQhull uq4; // Default constructors disabled.
-}//t_UsingLibQhull
-
-void UsingLibQhull_test::
-t_methods()
-{
- Qhull q;
- UsingLibQhull u(&q); // Normally created in a method using 'this'
- QVERIFY(u.defined());
- u.maybeThrowQhullMessage(0); // Nothing thrown
- try{
- u.maybeThrowQhullMessage(1);
- QFAIL("maybeThrowQhullMessage(1) did not fail.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- // Can not check checkRunId() in maybeThrowQhullMessage(). Requires another thread.
- u.maybeThrowQhullMessage(2, UsingLibQhull::NOthrow);
- try{
- throw QhullError(10054, "Report previous NOthrow error");
- }catch (const std::exception &e) {
- cout << "INFO : " << e.what();
- }
-}//t_methods
-
-// Executed after last test
-void UsingLibQhull_test::
-t_cleanuptestcase()
-{
- UsingLibQhull::unsetGlobals();
-}//t_cleanuptestcase
-
-}//orgQhull
-
-#include "moc/UsingLibQhull_test.moc"
-
diff --git a/src/qhullptest/qhullptest.cpp b/src/qhullptest/qhullptest.cpp
deleted file mode 100644
index 059e350..0000000
--- a/src/qhullptest/qhullptest.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhullptest/qhullptest.cpp#2 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <stdexcept>
-#include "RoadTest.h"
-
-#include "../libqhullcpp/RoadError.h"
-
-using std::cout;
-using std::endl;
-
-namespace orgQhull {
-
-void addQhullTests(QStringList &args)
-{
- TESTadd_(add_QhullVertex_test); //copy
-
- 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_RboxPoints_test);
- TESTadd_(add_UsingLibQhull_test);
- // needs review
- // 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");
- 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 with eg/q_test" << endl;
- }else{
- cout << "Finished test of one class. Test all classes with 'qhulltest --all'" << endl;
- }
- return status;
-}
-
-}//orgQhull
-
-int main(int argc, char *argv[])
-{
- return orgQhull::main(argc, argv); // Needs RoadTest:: for TESTadd_() linkage
-}
-
diff --git a/src/qhullptest/qhullptest.pro b/src/qhullptest/qhullptest.pro
deleted file mode 100644
index d9cedaf..0000000
--- a/src/qhullptest/qhullptest.pro
+++ /dev/null
@@ -1,34 +0,0 @@
-# -------------------------------------------------
-# qhulltest.pro -- Qt project for qhullptest.exe (QTestLib)
-# -------------------------------------------------
-
-include(../qhull-app-cpp.pri)
-
-TARGET = qhullptest
-CONFIG += qtestlib
-MOC_DIR = moc
-INCLUDEPATH += .. # for MOC_DIR
-
-PRECOMPILED_HEADER = RoadTest.h
-
-SOURCES += ../libqhullpcpp/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 += qhullptest.cpp
-SOURCES += QhullVertex_test.cpp
-SOURCES += RboxPoints_test.cpp
-SOURCES += RoadTest.cpp
-SOURCES += UsingLibQhull_test.cpp
-
-HEADERS += RoadTest.h
diff --git a/src/qhullr/qhullr.pro b/src/qhullr/qhullr.pro
deleted file mode 100644
index a1ad790..0000000
--- a/src/qhullr/qhullr.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-# -------------------------------------------------
-# qhullr.pro -- Qt project file for qhullr.exe
-# -------------------------------------------------
-
-include(../qhull-app-c_r.pri)
-
-TARGET = qhullr
-
-SOURCES += unix_r.c
diff --git a/src/qhulltest/Coordinates_test.cpp b/src/qhulltest/Coordinates_test.cpp
index d771bf8..938ff1e 100644
--- a/src/qhulltest/Coordinates_test.cpp
+++ b/src/qhulltest/Coordinates_test.cpp
@@ -1,534 +1,539 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/Coordinates_test.cpp#6 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/Coordinates_test.cpp#12 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
-#include "RoadTest.h" // QT_VERSION
+#include "qhulltest/RoadTest.h" // QT_VERSION
-#include "Coordinates.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
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<coordT> 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<coordT> vc= c.toStdVector();
- QCOMPARE(vc.size(), c.size());
- for(size_t k= vc.size(); k--; ){
+ QCOMPARE((size_t)vc.size(), c.size());
+ for(int k= (int)vc.size(); k--; ){
QCOMPARE(vc[k], c[k]);
}
QList<coordT> qc= c.toQList();
QCOMPARE(qc.count(), c.count());
for(int k= qc.count(); k--; ){
QCOMPARE(qc[k], c[k]);
}
Coordinates c4;
c4= std::vector<double>(2, 0.0);
QCOMPARE(c4.back(), 0.0);
Coordinates c5(std::vector<double>(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.empty());
QVERIFY(c.isEmpty());
c << 1.0 << -2.0;
QCOMPARE(c.size(), 2u);
QCOMPARE(c.count(), 2);
- QVERIFY(!c.empty());
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.end());
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.end());
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/qhulltest/PointCoordinates_test.cpp b/src/qhulltest/PointCoordinates_test.cpp
index 14a4268..0469903 100644
--- a/src/qhulltest/PointCoordinates_test.cpp
+++ b/src/qhulltest/PointCoordinates_test.cpp
@@ -1,478 +1,478 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/PointCoordinates_test.cpp#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/PointCoordinates_test.cpp#15 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
-#include "RoadTest.h" // QT_VERSION
+#include "qhulltest/RoadTest.h" // QT_VERSION
-#include "PointCoordinates.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
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);
+ PointCoordinates pc7(q, 2, "test explicit dimension");
QCOMPARE(pc7.dimension(), 2);
QCOMPARE(pc7.count(), 0);
QVERIFY(pc7.isEmpty());
- QVERIFY(pc7.comment().empty());
+ 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<coordT> 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);
+ 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);
+ PointCoordinates pc7(&qh, 2, "test explicit dimension");
QCOMPARE(pc7.dimension(), 2);
QCOMPARE(pc7.count(), 0);
QVERIFY(pc7.isEmpty());
- QVERIFY(pc7.comment().empty());
+ QCOMPARE(pc7.comment(), std::string("test explicit dimension"));
pc7.checkValid();
- PointCoordinates pc2(qh, "Test pc2");
+ 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");
+ 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);
+ 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);
+ 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<coordT> 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]);
+ 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);
+ 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<coordT> vs= ps.toStdVector();
QCOMPARE(vs.size(), 6u);
QCOMPARE(vs[5], 5.0);
QList<coordT> 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);
+ 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);
+ 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(2, c2);
+ 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);
- c << 1.0 << 2.0 << 3.0 << 1.0 << 2.0 << 3.0;
ostringstream os;
os << "PointCoordinates 0-d\n" << c;
c.setDimension(2);
- os << "PointCoordinates 1-3-2\n" << c;
+ 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"), 4);
+ QCOMPARE(s.count("2"), 5);
}//t_io
}//orgQhull
#include "moc/PointCoordinates_test.moc"
diff --git a/src/qhulltest/Point_test.cpp b/src/qhulltest/Point_test.cpp
deleted file mode 100644
index bd181e1..0000000
--- a/src/qhulltest/Point_test.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/Point_test.cpp#5 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-#include <iostream>
-using std::cout;
-using std::endl;
-#include "RoadTest.h" // QT_VERSION
-
-#include "QhullPoint.h"
-
-#include "Qhull.h"
-
-namespace orgQhull {
-
-class Point_test : public RoadTest
-{
- Q_OBJECT
-
-#//Test slots
-private slots:
- void initTestCase();
- void t_construct();
- void t_getset();
- void t_operator();
- void t_const_iterator();
- void t_iterator();
- void t_point_iterator();
- // void t_mutable_point_iterator();
- // void t_io();
-};//Point_test
-
-void
-add_Point_test()
-{
- new Point_test();
-}
-
-void Point_test::
-initTestCase(){
- RboxPoints rcube("c");
- Qhull q(rcube, "");
- UsingQhullLib::setGlobals();
-}//initTestCase
-
-void Point_test::
-t_construct()
-{
- QhullPoint p;
- QCOMPARE(p.dimension(), 0);
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoint p2;
- p2.defineAs(3, c);
- QCOMPARE(p2.dimension(), 3);
- QCOMPARE(p2.coordinates(), c);
- coordT c2[]= {0.0, 1.0, 2.0};
- QhullPoint p3(3, c2);
- QVERIFY(p3==p2);
- QhullPoint p5(p3);
- QVERIFY(p5==p3);
-}//t_construct
-
-void Point_test::
-t_getset()
-{
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoint p(3, c);
- QCOMPARE(p.coordinates(), c);
- QCOMPARE(p.dimension(), 3);
- QCOMPARE(p[2], 2.0);
- QhullPoint p2(p);
- p2.defineAs(p);
- QVERIFY(p2==p);
- QVERIFY(p2.coordinates()==p.coordinates());
- QVERIFY(p2.dimension()==p.dimension());
- p2.setDimension(2);
- QCOMPARE(p2.dimension(), 2);
- QVERIFY(p2!=p);
- coordT c2[]= {0.0, 1.0};
- p2.setCoordinates(c2);
- QCOMPARE(p2.coordinates(), c2);
- p.defineAs(2, c);
- QVERIFY(p2==p);
- QCOMPARE(p[1], 1.0);
-}//t_getset
-
-void Point_test::
-t_operator()
-{
- QhullPoint p;
- QhullPoint p2(p);
- QVERIFY(p==p2);
- QVERIFY(!(p!=p2));
- coordT c[]= {0.0, 1.0, 2.0};
- QhullPoint p3(3, c);
- QVERIFY(p3!=p2);
- QhullPoint p4(p3);
- QVERIFY(p4==p3);
- coordT c5[]= {5.0, 6.0, 7.0};
- QhullPoint p5(3, c5);
- QVERIFY(p5!=p3);
- QCOMPARE(p5[1], 6.0);
- QCOMPARE(p5[0], 5.0);
- const coordT *c0= &p5[0];
- QCOMPARE(*c0, 5.0);
-}//t_operator
-
-void Point_test::
-t_const_iterator()
-{
- coordT c[]= {1.0, 2.0, 3.0};
- QhullPoint p(3, c);
- QhullPoint::const_iterator i(p.coordinates());
- QhullPoint::const_iterator i2= p.coordinates();
- QVERIFY(i==i2);
- QVERIFY(i>=i2);
- QVERIFY(i<=i2);
- QCOMPARE(*i, 1.0);
- QCOMPARE(*(i+1), 2.0);
- QCOMPARE(*(i+1), i[1]);
- i= p.end();
- QVERIFY(i!=i2);
- i= i2;
- QVERIFY(i==i2);
- i= p.end();
- i= p.begin();
- QCOMPARE(*i, 1.0);
- QhullPoint::ConstIterator i3= p.end();
- QCOMPARE(*(i3-1), 3.0);
- QCOMPARE(*(i3-1), i3[-1]);
- QVERIFY(i!=i3);
- QVERIFY(i<i3);
- QVERIFY(i<=i3);
- QVERIFY(i3>i);
- QVERIFY(i3>=i);
-}//t_const_iterator
-
-
-void Point_test::
-t_iterator()
-{
- coordT c[]= {1.0, 2.0, 3.0};
- QhullPoint p(3, c);
- QhullPoint::Iterator i(p.coordinates());
- QhullPoint::iterator i2= p.coordinates();
- QVERIFY(i==i2);
- QVERIFY(i>=i2);
- QVERIFY(i<=i2);
- QCOMPARE(*i, 1.0);
- QCOMPARE(*(i+1), 2.0);
- QCOMPARE(*(i+1), i[1]);
- i= p.end();
- QVERIFY(i!=i2);
- i= i2;
- QVERIFY(i==i2);
- i= p.end();
- i= p.begin();
- QCOMPARE(*i, 1.0);
- QhullPoint::Iterator i3= p.end();
- QCOMPARE(*(i3-1), 3.0);
- QCOMPARE(*(i3-1), i3[-1]);
- QVERIFY(i!=i3);
- QVERIFY(i<i3);
- QVERIFY(i<=i3);
- QVERIFY(i3>i);
- QVERIFY(i3>=i);
- // compiler errors -- QhullPoint is const-only
- // QCOMPARE((i[0]= -10.0), -10.0);
- // coordT *c3= &i3[1];
-}//t_iterator
-
-void Point_test::
-t_point_iterator()
-{
- coordT c[]= {1.0, 3.0, 4.0};
- QhullPoint p(3, c);
- QhullPointIterator i(p);
- QhullPointIterator i2= p;
- 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());
-
- coordT c2[]= {1.0, 3.0, 4.0};
- QhullPoint p2(0, c2); // 0-dimensional
- i2= p2;
- QVERIFY(!i2.hasNext());
- QVERIFY(!i2.hasPrevious());
- i2.toBack();
- QVERIFY(!i2.hasNext());
- QVERIFY(!i2.hasPrevious());
- QCOMPARE(i.peekPrevious(), 4.0);
- QCOMPARE(i.previous(), 4.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);
- QCOMPARE(i.next(), 4.0);
- QVERIFY(!i.hasNext());
- i.toFront();
- QCOMPARE(i.next(), 1.0);
-}//t_point_iterator
-
-// No MutableQhullPointIterator since QhullPoint is const-only
-
-#if 0
-
-void Point_test::
-t_io()
-{
- QhullPoint p;
- cout<< "INFO: empty point" << p << endl;
- const coordT c[]= {1.0, 3.0, 4.0};
- QhullPoint p2(2, c); // 2-dimensional
- cout<< "INFO: " << p2 << endl;
-}//t_io
-
-error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class orgQhull::QhullPoint &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVPoint@orgQhull@@@Z) referenced in function "private: void __thiscall orgQhull::Point_test::t_io(void)" (?t_io@Point_test@orgQhull@@AAEXXZ)
-
-#endif
-
-}//orgQhull
-
-#include "moc/Point_test.moc"
diff --git a/src/qhulltest/QhullFacetList_test.cpp b/src/qhulltest/QhullFacetList_test.cpp
index 2c0b5da..f1b7019 100644
--- a/src/qhulltest/QhullFacetList_test.cpp
+++ b/src/qhulltest/QhullFacetList_test.cpp
@@ -1,200 +1,202 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullFacetList_test.cpp#7 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullFacetList_test.cpp#11 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
-#include "RoadTest.h" // QT_VERSION
+#include "qhulltest/RoadTest.h" // QT_VERSION
-#include "QhullFacetList.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "QhullVertexSet.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
//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<QhullFacet> fv= fs2.toStdVector();
QCOMPARE(fv.size(), 6u);
q.checkAndFreeQhullMemory();
}//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<QhullFacet> fv= fs2.toStdVector();
QCOMPARE(fv.size(), 6u);
q.checkAndFreeQhullMemory();
}//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<QhullFacet> fv= fs2.toStdVector();
QCOMPARE(fv.size(), 3u);
QList<QhullFacet> fv2= fs2.toQList();
QCOMPARE(fv2.size(), 3);
std::vector<QhullVertex> fv5= fs2.vertices_toStdVector();
QCOMPARE(fv5.size(), 7u);
QList<QhullVertex> fv6= fs2.vertices_toQList();
QCOMPARE(fv6.size(), 7);
fs2.selectAll();
QVERIFY(fs2.isSelectAll());
std::vector<QhullFacet> fv3= fs2.toStdVector();
QCOMPARE(fv3.size(), 6u);
QList<QhullFacet> fv4= fs2.toQList();
QCOMPARE(fv4.size(), 6);
std::vector<QhullVertex> fv7= fs2.vertices_toStdVector();
QCOMPARE(fv7.size(), 8u);
QList<QhullVertex> fv8= fs2.vertices_toQList();
QCOMPARE(fv8.size(), 8);
q.checkAndFreeQhullMemory();
}//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));
q.checkAndFreeQhullMemory();
}//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());
q.checkAndFreeQhullMemory();
}//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(); // Runs all print options
- os << "\nFacets only\n" << fs;
- os << "\nVertices\n" << fs.printVertices()
+ 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"), 7+12*3*2);
- QCOMPARE(facets.count(QRegExp("f\\d")), 3*7 + 13*3*2);
+ QCOMPARE(facets.count("(v"), 2*7+12*3*2);
+ QCOMPARE(facets.count(QRegExp("f\\d")), 2*3*7 + 13*3*2);
q.checkAndFreeQhullMemory();
}
}//t_io
}//orgQhull
#include "moc/QhullFacetList_test.moc"
diff --git a/src/qhulltest/QhullFacetSet_test.cpp b/src/qhulltest/QhullFacetSet_test.cpp
index f1de14b..f56d6af 100644
--- a/src/qhulltest/QhullFacetSet_test.cpp
+++ b/src/qhulltest/QhullFacetSet_test.cpp
@@ -1,157 +1,158 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullFacetSet_test.cpp#7 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullFacetSet_test.cpp#12 $$Change: 1880 $
+** $DateTime: 2015/04/19 21:29:35 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
-#include "RoadTest.h"
+#include "qhulltest/RoadTest.h"
-#include "QhullFacetSet.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
//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.qhullQh()->facet_mergeset);
+ QhullFacetSet fs3(q, q.qh()->facet_mergeset);
QVERIFY(fs3.isEmpty());
q.checkAndFreeQhullMemory();
}//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<QhullFacet> fv= fs2.toStdVector();
QCOMPARE(fv.size(), 2u);
QList<QhullFacet> fv2= fs2.toQList();
QCOMPARE(fv2.size(), 2);
fs2.selectAll();
QVERIFY(fs2.isSelectAll());
std::vector<QhullFacet> fv3= fs2.toStdVector();
QCOMPARE(fv3.size(), 4u);
QList<QhullFacet> fv4= fs2.toQList();
QCOMPARE(fv4.size(), 4);
q2.checkAndFreeQhullMemory();
}//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));
q.checkAndFreeQhullMemory();
}//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)){
+ 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());
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}
}//t_io
}//orgQhull
#include "moc/QhullFacetSet_test.moc"
diff --git a/src/qhulltest/QhullFacet_test.cpp b/src/qhulltest/QhullFacet_test.cpp
index 11cb7f4..c3c4259 100644
--- a/src/qhulltest/QhullFacet_test.cpp
+++ b/src/qhulltest/QhullFacet_test.cpp
@@ -1,283 +1,288 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullFacet_test.cpp#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullFacet_test.cpp#14 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
-#include "RoadTest.h"
+#include "qhulltest/RoadTest.h"
-#include "QhullFacet.h"
-#include "QhullError.h"
-#include "Coordinates.h"
-#include "RboxPoints.h"
-#include "QhullFacetList.h"
-#include "QhullFacetSet.h"
-#include "QhullPointSet.h"
-#include "QhullRidge.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
//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.isDefined());
+ 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;
+ Qhull q2;
QhullFacet f(q2);
- QVERIFY(!f.isDefined());
+ 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.isDefined());
+ QVERIFY(f.isValid());
QCOMPARE(f.dimension(),3);
QhullFacet f5= f2;
QVERIFY(f5==f2);
QVERIFY(f5==f);
- QhullFacet f3= f2.getFacetT();
+ QhullFacet f3(q, f2.getFacetT());
QCOMPARE(f,f3);
- QhullFacet f4= f2.getBaseT();
+ QhullFacet f4(q, f2.getBaseT());
QCOMPARE(f,f4);
q.checkAndFreeQhullMemory();
q2.checkAndFreeQhullMemory();
}//t_constructConvert
void QhullFacet_test::
t_getSet()
{
RboxPoints rcube("c");
{
Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
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.isDefined());
+ QVERIFY(f.isValid());
if(i.hasNext()){
QCOMPARE(f.next(), i.peekNext());
QVERIFY(f.next()!=f);
}
QVERIFY(i.hasPrevious());
QCOMPARE(f, i.peekPrevious());
}
- QhullFacetListIterator i2(i);
- QEXPECT_FAIL("", "ListIterator copy constructor not reset to BOT", Continue);
- QVERIFY(!i2.hasPrevious());
// 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 << endl;
+ 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;
+ cout << "InnerPlane: " << hi << " innerOffset+0.5 " << innerOffset << endl;
QVERIFY(innerOffset >= 0.0);
QhullHyperplane ho= f.outerplane();
QCOMPARE(ho.count(), 3);
double outerOffset= ho.offset()+0.5;
- cout << "OuterPlane: " << ho << "outerOffset+0.5 " << outerOffset << endl;
+ cout << "OuterPlane: " << ho << " outerOffset+0.5 " << outerOffset << endl;
QVERIFY(outerOffset <= 0.0);
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 << endl;
+ 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)
QhullFacet f2= q2.firstFacet();
QhullPoint center3= f2.getCenter(qh_PRINTtriangles);
QCOMPARE(center3.dimension(), 3);
QhullPoint center4= f2.getCenter();
- QCOMPARE(center4.dimension(), 3);
+ 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)
- q->setFactorEpsilon(100); // Voronoi vertices are not necessarily within distance episilon
+ q3.setFactorEpsilon(100); // 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()){
- QhullPoint p= f.voronoiVertex(q3.runId());
- cout << p.print(q3.runId(), "Voronoi vertex: ")
- << " DistanceEpsilon " << q->distanceEpsilon() << endl;
- QCOMPARE(p, q3.origin());
+ ++voronoiCount;
+ QhullPoint p= f.voronoiVertex();
+ cout << p.print("Voronoi vertex: ")
+ << " DistanceEpsilon " << q3.distanceEpsilon() << endl;
+ QCOMPARE(p, origin);
}
}
+ QCOMPARE(voronoiCount, 1);
q.checkAndFreeQhullMemory();
q2.checkAndFreeQhullMemory();
q3.checkAndFreeQhullMemory();
}
}//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
}
+ q.checkAndFreeQhullMemory();
}
- q.checkAndFreeQhullMemory();
}//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);
+ q.checkAndFreeQhullMemory();
}
- q.checkAndFreeQhullMemory();
}//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.printCenter(qh_PRINTfacets, " - center: ");
os << f.printRidges();
cout << os.str();
ostringstream os2;
- os2 << f.print(); // invokes print*()
+ os2 << f;
QString facetString2= QString::fromStdString(os2.str());
facetString2.replace(QRegExp("\\s\\s+"), " ");
ostringstream os3;
- q.setOutputStream(&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);
+ q.checkAndFreeQhullMemory();
}
- q.checkAndFreeQhullMemory();
}//t_io
// toQhullFacet is static_cast only
}//orgQhull
#include "moc/QhullFacet_test.moc"
diff --git a/src/qhulltest/QhullHyperplane_test.cpp b/src/qhulltest/QhullHyperplane_test.cpp
index 483f673..bf835fc 100644
--- a/src/qhulltest/QhullHyperplane_test.cpp
+++ b/src/qhulltest/QhullHyperplane_test.cpp
@@ -1,421 +1,440 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullHyperplane_test.cpp#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullHyperplane_test.cpp#15 $$Change: 1880 $
+** $DateTime: 2015/04/19 21:29:35 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include <vector>
-#include "RoadTest.h"
-
-#include "QhullHyperplane.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "Qhull.h"
+#include "qhulltest/RoadTest.h"
+
+#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 <numeric>
using std::cout;
using std::endl;
using std::ostringstream;
using std::ostream;
using std::string;
namespace orgQhull {
class QhullHyperplane_test : public RoadTest
{
Q_OBJECT
-#//Test slots
+#//!\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();
}
//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
- QhullHyperplane h;
- QVERIFY(!h.isDefined());
- QCOMPARE(h.dimension(),0);
+ 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<double *>(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);
+ q.checkAndFreeQhullMemory();
+}//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.isDefined());
- QCOMPARE(h2.dimension(),3);
+ QVERIFY(h2.isValid());
+ QCOMPARE(h2.dimension(), 3);
// h= h2; // copy assignment disabled, ambiguous
- QhullHyperplane h3(h2.dimension(), h2.coordinates(), h2.offset());
+ QhullHyperplane h3(q.qh(), h2.dimension(), h2.coordinates(), h2.offset());
QCOMPARE(h2, h3);
QhullHyperplane h5= h2; // copy constructor
QVERIFY(h5==h2);
q.checkAndFreeQhullMemory();
-}//t_construct
+}//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<double> 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<double> 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);
q.checkAndFreeQhullMemory();
}//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.isDefined());
+ 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());
q.checkAndFreeQhullMemory();
}
}//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);
q.checkAndFreeQhullMemory();
}
}//t_define
void QhullHyperplane_test::
t_value()
{
RboxPoints rcube("c G1");
Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
- const QhullHyperplane h= q.firstFacet().hyperplane();
+ 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);
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}//t_operator
void QhullHyperplane_test::
t_iterator()
{
RboxPoints rcube("c");
{
- QhullHyperplane h2;
- QCOMPARE(h2.begin(), h2.end());
- QCOMPARE(h2.count(), 0);
- QCOMPARE(h2.size(), 0u);
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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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(i4<i2);
QVERIFY(i4<=i2);
++i4;
QVERIFY(i<i4);
QVERIFY(i<=i4);
QVERIFY(i4>i);
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
q.checkAndFreeQhullMemory();
}
}//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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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
q.checkAndFreeQhullMemory();
}
}//t_const_iterator
void QhullHyperplane_test::
t_qhullHyperplane_iterator()
{
- QhullHyperplane h2;
- QhullHyperplaneIterator i= h2;
- QCOMPARE(h2.dimension(), 0);
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
- i.toBack();
- QVERIFY(!i.hasNext());
- QVERIFY(!i.hasPrevious());
-
RboxPoints rcube("c");
Qhull q(rcube,"QR0"); // rotated unit cube
QhullHyperplane h = q.firstFacet().hyperplane();
QhullHyperplaneIterator i2(h);
QCOMPARE(h.dimension(), 3);
- i= h;
+ 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]);
q.checkAndFreeQhullMemory();
}//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 << "Hyperplane as print(), FIXUP drop?\n";
- os << h.print();
+ 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);
q.checkAndFreeQhullMemory();
}
}//t_io
}//orgQhull
#include "moc/QhullHyperplane_test.moc"
diff --git a/src/qhulltest/QhullLinkedList_test.cpp b/src/qhulltest/QhullLinkedList_test.cpp
index 2a60ff7..2563038 100644
--- a/src/qhulltest/QhullLinkedList_test.cpp
+++ b/src/qhulltest/QhullLinkedList_test.cpp
@@ -1,335 +1,337 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullLinkedList_test.cpp#7 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullLinkedList_test.cpp#11 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <QtCore/QList>
-#include "RoadTest.h"
+#include "qhulltest/RoadTest.h"
-#include "QhullLinkedList.h"
-#include "Qhull.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
-#//Test slots
+#//!\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();
}
//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);
q.checkAndFreeQhullMemory();
}
}//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<QhullVertex> 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<QhullVertex> vs3= vs.toQList();
QCOMPARE(vs3.count(), vs.count());
i= vs.begin();
for(int k= 0; k<vs3.count(); k++){
QCOMPARE(vs3[k], *i++);
}
QhullVertexList vs4(q.endVertex(), q.endVertex());
QVERIFY(vs4.isEmpty());
QVERIFY(vs==vs);
QVERIFY(vs4==vs4);
QVERIFY(vs!=vs4);
q.checkAndFreeQhullMemory();
}
}//t_convert
//ReadOnly tested by t_convert
void QhullLinkedList_test::
t_element()
{
RboxPoints rcube("c");
Qhull q(rcube,"QR0"); // rotated unit cube
QhullVertexList vs = q.vertexList();
QhullVertex v= vs.first();
QCOMPARE(v.previous(), QhullVertex(NULL));
QCOMPARE(vs.front(), vs.first());
QhullVertex v2= vs.last();
QCOMPARE(v2.next().next(), QhullVertex(NULL)); // sentinel has NULL next
QCOMPARE(vs.back(), vs.last());
q.checkAndFreeQhullMemory();
}//t_element
void QhullLinkedList_test::
t_search()
{
RboxPoints rcube("c");
Qhull q(rcube,"QR0"); // rotated unit cube
QhullVertexList vs = q.vertexList();
- QhullVertex v;
+ QhullVertex v(q);
QVERIFY(!vs.contains(v));
QCOMPARE(vs.count(v), 0);
QhullVertex v2= *vs.begin();
QhullVertex v3= vs.last();
QVERIFY(vs.contains(v2));
QCOMPARE(vs.count(v2), 1);
QVERIFY(vs.contains(v3));
QCOMPARE(vs.count(v3), 1);
q.checkAndFreeQhullMemory();
}//t_search
void QhullLinkedList_test::
t_iterator()
{
RboxPoints rcube("c");
{
Qhull q(rcube,"QR0"); // rotated unit cube
QhullVertexList vs = q.vertexList();
QhullVertexList::Iterator i= vs.begin();
QhullVertexList::iterator i2= vs.begin();
QVERIFY(i==i2);
// No comparisons
i= vs.begin();
QVERIFY(i==i2);
i2= vs.end();
QVERIFY(i!=i2);
QhullVertex v3(*i);
i2--;
QhullVertex v8= *i2;
QhullVertex v= vs.first();
QhullVertex v2= v.next();
QCOMPARE(v3.id(), v.id());
QCOMPARE(v8.id(), vs.last().id());
QhullVertexList::Iterator i3(i2);
QCOMPARE(*i2, *i3);
(i3= i)++;
QCOMPARE((*i3).id(), v2.id());
QVERIFY(i==i);
QVERIFY(i!=i2);
QhullVertexList::ConstIterator i4= vs.begin();
QVERIFY(i==i4); // iterator COMP const_iterator
QVERIFY(i4==i); // const_iterator COMP iterator
QVERIFY(i2!=i4);
QVERIFY(i4!=i2);
++i4;
i= vs.begin();
i2= vs.begin();
QCOMPARE(i, i2++);
QCOMPARE(*i2, v2);
QCOMPARE(++i, i2);
QCOMPARE(i, i2--);
QCOMPARE(i2, vs.begin());
QCOMPARE(--i, i2);
QCOMPARE(i2 += 8, vs.end());
QCOMPARE(i2 -= 8, vs.begin());
QCOMPARE(i2+0, vs.begin());
QCOMPARE(i2+8, vs.end());
i2 += 8;
i= i2-0;
QCOMPARE(i, i2);
i= i2-8;
QCOMPARE(i, vs.begin());
//vs.begin end tested above
// QhullVertexList is const-only
q.checkAndFreeQhullMemory();
}
}//t_iterator
void QhullLinkedList_test::
t_const_iterator()
{
RboxPoints rcube("c");
{
Qhull q(rcube,"QR0"); // rotated unit cube
QhullVertexList vs = q.vertexList();
QhullVertexList::ConstIterator i= vs.begin();
QhullVertexList::const_iterator i2= vs.begin();
QVERIFY(i==i2);
i= vs.begin();
QVERIFY(i==i2);
i2= vs.end();
QVERIFY(i!=i2);
QhullVertex v3(*i);
i2--;
QhullVertex v8= *i2;
QhullVertex v= vs.first();
QhullVertex v2= v.next();
QCOMPARE(v3.id(), v.id());
QCOMPARE(v8.id(), vs.last().id());
QhullVertexList::ConstIterator i3(i2);
QCOMPARE(*i2, *i3);
(i3= i)++;
QCOMPARE((*i3).id(), v2.id());
QVERIFY(i==i);
QVERIFY(i!=i2);
// See t_iterator for const_iterator COMP iterator
i= vs.begin();
i2= vs.constBegin();
QCOMPARE(i, i2++);
QCOMPARE(*i2, v2);
QCOMPARE(++i, i2);
QCOMPARE(i, i2--);
QCOMPARE(i2, vs.constBegin());
QCOMPARE(--i, i2);
QCOMPARE(i2 += 8, vs.constEnd());
QCOMPARE(i2 -= 8, vs.constBegin());
QCOMPARE(i2+0, vs.constBegin());
QCOMPARE(i2+8, vs.constEnd());
i2 += 8;
i= i2-0;
QCOMPARE(i, i2);
i= i2-8;
QCOMPARE(i, vs.constBegin());
// QhullVertexList is const-only
q.checkAndFreeQhullMemory();
}
}//t_const_iterator
void QhullLinkedList_test::
t_QhullLinkedList_iterator()
{
RboxPoints rcube("c");
Qhull q(rcube,"QR0"); // rotated unit cube
QhullVertexList vs(q.endVertex(), q.endVertex());
QhullVertexListIterator i= vs;
QCOMPARE(vs.count(), 0);
QVERIFY(!i.hasNext());
QVERIFY(!i.hasPrevious());
i.toBack();
QVERIFY(!i.hasNext());
QVERIFY(!i.hasPrevious());
QhullVertexList vs2 = q.vertexList();
QhullVertexListIterator i2(vs2);
QCOMPARE(vs2.count(), 8);
i= vs2;
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
QhullVertexList vs3 = q.vertexList(); // same as vs2
QhullVertex v3(vs3.first());
QhullVertex v4= vs3.first();
QCOMPARE(v3, v4);
QVERIFY(v3==v4);
QhullVertex v5(v4.next());
QVERIFY(v4!=v5);
QhullVertex v6(v5.next());
QhullVertex v7(v6.next());
QhullVertex v8(vs3.last());
QCOMPARE(i2.peekPrevious(), v8);
i2.previous();
i2.previous();
i2.previous();
i2.previous();
QCOMPARE(i2.previous(), v7);
QCOMPARE(i2.previous(), v6);
QCOMPARE(i2.previous(), v5);
QCOMPARE(i2.previous(), v4);
QVERIFY(!i2.hasPrevious());
QCOMPARE(i.peekNext(), v4);
// i.peekNext()= 1.0; // compiler error
QCOMPARE(i.next(), v4);
QCOMPARE(i.peekNext(), v5);
QCOMPARE(i.next(), v5);
QCOMPARE(i.next(), v6);
QCOMPARE(i.next(), v7);
i.next();
i.next();
i.next();
QCOMPARE(i.next(), v8);
QVERIFY(!i.hasNext());
i.toFront();
QCOMPARE(i.next(), v4);
q.checkAndFreeQhullMemory();
}//t_QhullLinkedList_iterator
void QhullLinkedList_test::
t_io()
{
RboxPoints rcube("c");
Qhull q(rcube,"QR0"); // rotated unit cube
QhullVertexList vs(q.endVertex(), q.endVertex());
std::cout << "INFO: empty QhullVertextList" << vs << std::endl;
QhullVertexList vs2= q.vertexList();
std::cout << "INFO: " << vs2 << std::endl;
q.checkAndFreeQhullMemory();
}//t_io
}//namespace orgQhull
#include "moc/QhullLinkedList_test.moc"
diff --git a/src/qhulltest/QhullPointSet_test.cpp b/src/qhulltest/QhullPointSet_test.cpp
index b0ae025..325c074 100644
--- a/src/qhulltest/QhullPointSet_test.cpp
+++ b/src/qhulltest/QhullPointSet_test.cpp
@@ -1,386 +1,386 @@
/****************************************************************************
**
** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullPointSet_test.cpp#13 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullPointSet_test.cpp#15 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled header
#include <iostream>
#include "RoadTest.h" // QT_VERSION
-#include "QhullPointSet.h"
-#include "RboxPoints.h"
-#include "QhullPoint.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
//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);
q.checkAndFreeQhullMemory();
}//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<QhullPoint> vs= ps.toStdVector();
QCOMPARE(vs.size(), ps.size());
QhullPoint p= ps[0];
QhullPoint p2= vs[0];
QCOMPARE(p, p2);
QList<QhullPoint> qs= ps.toQList();
QCOMPARE(qs.size(), static_cast<int>(ps.size()));
QhullPoint p3= qs[0];
QCOMPARE(p3, p);
q.checkAndFreeQhullMemory();
}//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++);
}
q.checkAndFreeQhullMemory();
}//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(i<i3);
QVERIFY(i<=i3);
QVERIFY(i3>i);
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(i4<i2);
QVERIFY(i4<=i2);
++i4;
QVERIFY(i!=i4); // iterator COMP const_iterator
QVERIFY(i<i4);
QVERIFY(i<=i4);
QVERIFY(i4>i);
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
q.checkAndFreeQhullMemory();
}//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(i<i3);
QVERIFY(i<=i3);
QVERIFY(i3>i);
QVERIFY(i3>=i);
// QhullPointSet is const-only
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}//t_io
}//orgQhull
#include "moc/QhullPointSet_test.moc"
diff --git a/src/qhulltest/QhullPoint_test.cpp b/src/qhulltest/QhullPoint_test.cpp
index a7d4eba..2cc3260 100644
--- a/src/qhulltest/QhullPoint_test.cpp
+++ b/src/qhulltest/QhullPoint_test.cpp
@@ -1,447 +1,447 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullPoint_test.cpp#11 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullPoint_test.cpp#14 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include "RoadTest.h"
-#include "QhullPoint.h"
-#include "Coordinates.h"
-#include "RboxPoints.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "QhullPoint.h"
-#include "Qhull.h"
+#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 <numeric>
using std::cout;
using std::endl;
using std::ostringstream;
using std::ostream;
using std::string;
namespace orgQhull {
class QhullPoint_test : public RoadTest
{
Q_OBJECT
-#//Test slots
+#//!\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();
}
//Executed after each test
void QhullPoint_test::
cleanup()
{
RoadTest::cleanup();
}
void QhullPoint_test::
t_construct()
{
QhullPoint p12;
- QVERIFY(!p12.isDefined());
+ 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.isDefined());
+ QVERIFY(!p.isValid());
QCOMPARE(p.dimension(),3);
QCOMPARE(p.coordinates(),static_cast<double *>(0));
QhullPoint p7(q.qh());
QCOMPARE(p, p7);
// copy constructor and copy assignment
QhullVertex v2(q.beginVertex());
QhullPoint p2(v2.point());
- QVERIFY(p2.isDefined());
+ QVERIFY(p2.isValid());
QCOMPARE(p2.dimension(),3);
QVERIFY(p2!=p12);
- p= p2;
+ 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);
q.checkAndFreeQhullMemory();
}//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<double> vs= p.toStdVector();
QCOMPARE(vs.size(), 3u);
for(int k=3; k--; ){
QCOMPARE(vs[k], p[k]);
}
QList<double> qs= p.toQList();
QCOMPARE(qs.size(), 3);
for(int k=3; k--; ){
QCOMPARE(qs[k], p[k]);
}
q.checkAndFreeQhullMemory();
}//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.isDefined());
+ 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());
q.checkAndFreeQhullMemory();
}
}//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);
q.checkAndFreeQhullMemory();
}
}//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);
q.checkAndFreeQhullMemory();
}//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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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(i4<i2);
QVERIFY(i4<=i2);
++i4;
QVERIFY(i<i4);
QVERIFY(i<=i4);
QVERIFY(i4>i);
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
q.checkAndFreeQhullMemory();
}
}//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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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
q.checkAndFreeQhullMemory();
}
}//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]);
q.checkAndFreeQhullMemory();
}//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
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}
}//t_io
}//orgQhull
#include "moc/QhullPoint_test.moc"
diff --git a/src/qhulltest/QhullPoints_test.cpp b/src/qhulltest/QhullPoints_test.cpp
index 03ca2a3..cbb93fc 100644
--- a/src/qhulltest/QhullPoints_test.cpp
+++ b/src/qhulltest/QhullPoints_test.cpp
@@ -1,486 +1,573 @@
/****************************************************************************
**
** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullPoints_test.cpp#10 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullPoints_test.cpp#15 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled header
#include <iostream>
-#include "RoadTest.h" // QT_VERSION
+#include "qhulltest/RoadTest.h" // QT_VERSION
-#include "QhullPoints.h"
-#include "RboxPoints.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\name Test slots
private slots:
void cleanup();
- void t_construct();
+ 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();
}
//Executed after each testcase
void QhullPoints_test::
cleanup()
{
RoadTest::cleanup();
}
void QhullPoints_test::
-t_construct()
+t_construct_q()
{
- QhullPoints ps;
+ 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;
+ 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 ps7(3);
- QCOMPARE(ps7.dimension(), 3);
- QVERIFY(ps7.isEmpty());
- QhullPoints ps3(2, 6, 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(2, 6, c2);
+ QhullPoints ps6(q, 2, 6, c2);
QVERIFY(ps6==ps2);
q.checkAndFreeQhullMemory();
-}//t_construct
+
+ 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);
+ q2.checkAndFreeQhullMemory();
+}//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);
+ q2.checkAndFreeQhullMemory();
+}//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(3, 6, c);
+ 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<QhullPoint> vs= ps.toStdVector();
QCOMPARE(vs.size(), 2u);
QhullPoint p= vs[1];
QCOMPARE(p[2], 5.0);
QList<QhullPoint> qs= ps.toQList();
QCOMPARE(qs.size(), 2);
QhullPoint p2= qs[1];
QCOMPARE(p2[2], 5.0);
q.checkAndFreeQhullMemory();
}//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(3, 6, c);
- QhullPoints ps2(3, 6, c);
+ 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(3);
+ 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()));
q.checkAndFreeQhullMemory();
}//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(2, 6, c);
- QhullPoint p(2, c);
+ 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;
+ 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);
}
q.checkAndFreeQhullMemory();
}//t_element
void QhullPoints_test::
t_iterator()
{
+ Qhull q;
coordT c[]= {0.0, 1.0, 2.0};
- QhullPoints ps(1, 3, c);
+ 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(1, c3);
+ 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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
QVERIFY(i2>=i);
- QhullPoints::ConstIterator i4(1, c);
+ 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(i4<i2);
QVERIFY(i4<=i2);
++i4;
QVERIFY(i<i4);
QVERIFY(i<=i4);
QVERIFY(i4>i);
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
q.checkAndFreeQhullMemory();
}//t_iterator
void QhullPoints_test::
t_const_iterator()
{
+ Qhull q;
coordT c[]= {0.0, 1.0, 2.0};
- const QhullPoints ps(1, 3, c);
+ 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(1, c3);
+ 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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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
q.checkAndFreeQhullMemory();
}//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(2, 8, c); //2-d array of 4 points
+ 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(2, c2); //2-d point
+ QhullPoint p3(q, 2, c2); //2-d point
QVERIFY(ps.contains(p3));
- QhullPoint p4(3, c2); //3-d point
+ 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(2, c2+2); //2-d point
+ 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 ps2(3);
- QCOMPARE(ps2.indexOf(ps2.data()), -1);
- QCOMPARE(ps2.indexOf(ps2.data()+1, QhullError::NOthrow), -1);
- QCOMPARE(ps2.indexOf(p), -1);
- QCOMPARE(ps2.lastIndexOf(p), -1);
- QhullPoints ps3;
+ 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(2, 0, c);
+ QhullPoints ps4(q, 2, 0, c);
QCOMPARE(ps4.indexOf(p), -1);
QCOMPARE(ps4.lastIndexOf(p), -1);
q.checkAndFreeQhullMemory();
}//t_search
void QhullPoints_test::
t_points_iterator()
{
+ Qhull q;
coordT c2[]= {0.0};
- QhullPoints ps2(0, 0, c2); // 0-dimensional
+ 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(3, 6, c); // 3-dimensional
+ 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);
q.checkAndFreeQhullMemory();
}//t_points_iterator
void QhullPoints_test::
t_io()
{
- QhullPoints ps;
+ 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(3, 6, c); // 3-dimensional explicit
+ QhullPoints ps2(q, 3, 6, c); // 3-dimensional explicit
os << "QhullPoints from c[]\n" << ps2 << endl;
+ q.checkAndFreeQhullMemory();
+
RboxPoints rcube("c");
- Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
- QhullPoints ps3= q.points();
+ Qhull q2(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullPoints ps3= q2.points();
os << "QhullPoints\n" << ps3;
- os << "RunId\n" << ps3.print();
- os << ps3.print("RunId w/ message\n");
- os << ps3.printWithIdentifier("RunId w/ identifiers\n");
+ os << ps3.print("message\n");
+ os << ps3.printWithIdentifier("w/ identifiers\n");
cout << os.str();
QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count("p"), 3*8+3);
- // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
- q.checkAndFreeQhullMemory();
+ QCOMPARE(s.count("p"), 8+1);
+ q2.checkAndFreeQhullMemory();
}//t_io
}//orgQhull
#include "moc/QhullPoints_test.moc"
diff --git a/src/qhulltest/QhullRidge_test.cpp b/src/qhulltest/QhullRidge_test.cpp
index 944dcf4..9478fdb 100644
--- a/src/qhulltest/QhullRidge_test.cpp
+++ b/src/qhulltest/QhullRidge_test.cpp
@@ -1,166 +1,163 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullRidge_test.cpp#8 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullRidge_test.cpp#11 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include "RoadTest.h"
-#include "QhullRidge.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacet.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
//Executed after each testcase
void QhullRidge_test::
cleanup()
{
RoadTest::cleanup();
}
void QhullRidge_test::
t_construct()
{
// Qhull.runQhull() constructs QhullFacets as facetT
- QhullRidge r;
- QVERIFY(!r.isDefined());
- QCOMPARE(r.dimension(),0);
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.isDefined());
+ QVERIFY(r.isValid());
QCOMPARE(r.dimension(), 2);
- QhullRidge r3= r2.getRidgeT();
+ QhullRidge r3(q, r2.getRidgeT());
QCOMPARE(r,r3);
- QhullRidge r4= r2.getBaseT();
+ QhullRidge r4(q, r2.getBaseT());
QCOMPARE(r,r4);
QhullRidge r5= r2; // copy constructor
QVERIFY(r5==r2);
QVERIFY(r5==r);
q.checkAndFreeQhullMemory();
}//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.isDefined());
+ QVERIFY(r.isValid());
QVERIFY(r==r);
QVERIFY(r==i.peekPrevious());
QCOMPARE(r.otherFacet(r.bottomFacet()),r.topFacet());
QCOMPARE(r.otherFacet(r.topFacet()),r.bottomFacet());
}
- QhullRidgeSetIterator i2(i);
- QEXPECT_FAIL("", "SetIterator copy constructor not reset to BOT", Continue);
- QVERIFY(!i2.hasPrevious());
q.checkAndFreeQhullMemory();
}
}//t_getSet
void QhullRidge_test::
t_foreach()
{
RboxPoints rcube("c"); // cube
{
Qhull q(rcube, "QR0"); // rotated cube
QhullFacet f(q.firstFacet());
foreach (QhullRidge r, f.ridges()){ // Qt only
QhullVertexSet vs= r.vertices();
QCOMPARE(vs.count(), 2);
- foreach (QhullVertex v, vs){ // Qt only
- QVERIFY(f.vertices().contains(v));
- }
+ //FIXUP foreach (const QhullVertex v, vs){ // Qt only
+ // QVERIFY(f.vertices().contains(v));
+ // }
}
QhullRidgeSet rs= f.ridges();
QhullRidge r= rs.first();
QhullRidge r2= r;
QList<QhullVertex> vs;
int count= 0;
while(!count || r2!=r){
++count;
- QhullVertex v;
+ 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());
q.checkAndFreeQhullMemory();
}
}//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 << "Ridge with runId FIXUP\n" << r.print();
+ os << r.print("\nRidge with message");
cout << os.str();
QString s= QString::fromStdString(os.str());
- QCOMPARE(s.count(" r"), 6+2);
+ QCOMPARE(s.count(" r"), 6);
q.checkAndFreeQhullMemory();
}
}//t_io
}//orgQhull
#include "moc/QhullRidge_test.moc"
diff --git a/src/qhulltest/QhullSet_test.cpp b/src/qhulltest/QhullSet_test.cpp
index 227bd5d..577ee52 100644
--- a/src/qhulltest/QhullSet_test.cpp
+++ b/src/qhulltest/QhullSet_test.cpp
@@ -1,439 +1,441 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullSet_test.cpp#7 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullSet_test.cpp#10 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include <QtCore/QList>
#include "RoadTest.h" // QT_VERSION
-#include "QhullRidge.h"
-#include "QhullFacetSet.h"
-#include "Qhull.h"
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/RboxPoints.h"
using std::cout;
using std::endl;
namespace orgQhull {
class QhullSet_test : public RoadTest
{
Q_OBJECT
-#//Test slots
+#//!\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();
}
//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.qhullQh()->other_points); // Force an empty set
+ 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);
q.checkAndFreeQhullMemory();
}
}//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<QhullRidge> rv= rs.toStdVector();
QCOMPARE(rv.size(), 4u);
QList<QhullRidge> rv2= rs.toQList();
QCOMPARE(rv2.size(), 4);
std::vector<QhullRidge>::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<QhullFacet> vs= fs.toStdVector();
QCOMPARE(vs.size(), fs.size());
for(int k= fs.count(); k--; ){
QCOMPARE(vs[k], fs[k]);
}
QList<QhullFacet> qv= fs.toQList();
QCOMPARE(qv.count(), fs.count());
for(int k= fs.count(); k--; ){
QCOMPARE(qv[k], fs[k]);
}
q.checkAndFreeQhullMemory();
}
}//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());
- QhullFacet *d= fs.data();
- const QhullFacet *d2= fs.data();
- const QhullFacet *d3= fs.constData();
+ facetT **d = fs.data();
+ facetT * const *d2= fs.data();
+ facetT * const *d3= fs.constData();
QVERIFY(d==d2);
QVERIFY(d2==d3);
- QCOMPARE(*d, fs.first());
- QCOMPARE(d+4, fs.end());
- QCOMPARE((d+4)->getFacetT(), static_cast<facetT *>(0));
- QhullFacet f4= *(d+4);
- QVERIFY(!f4.isDefined());
+ QCOMPARE(QhullFacet(q, *d), fs.first());
+ QhullFacetSet::iterator i(q.qh(), d+4);
+ QCOMPARE(i, fs.end());
+ QCOMPARE(d[4], static_cast<facetT *>(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)
q.checkAndFreeQhullMemory();
}//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);
q.checkAndFreeQhullMemory();
}//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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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(i4<i2);
QVERIFY(i4<=i2);
++i4;
QVERIFY(i<i4);
QVERIFY(i<=i4);
QVERIFY(i4>i);
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
q.checkAndFreeQhullMemory();
}
}//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(i<i2);
QVERIFY(i<=i2);
QVERIFY(i2>i);
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
q.checkAndFreeQhullMemory();
}
}//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.qhullQh()->other_points);
- QhullFacetSetIterator i= fs;
+ 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);
q.checkAndFreeQhullMemory();
}//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.qhullQh()->other_points);
+ 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;
q.checkAndFreeQhullMemory();
}//t_io
}//namespace orgQhull
#include "moc/QhullSet_test.moc"
diff --git a/src/qhulltest/QhullVertexSet_test.cpp b/src/qhulltest/QhullVertexSet_test.cpp
index 99bb49b..2a8f25d 100644
--- a/src/qhulltest/QhullVertexSet_test.cpp
+++ b/src/qhulltest/QhullVertexSet_test.cpp
@@ -1,185 +1,172 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullVertexSet_test.cpp#4 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullVertexSet_test.cpp#10 $$Change: 1880 $
+** $DateTime: 2015/04/19 21:29:35 $$Author: bbarber $
**
****************************************************************************/
#include <iostream>
-#include "../road/RoadTest.h" // FIXUP First for QHULL_USES_QT
+#include "qhulltest/RoadTest.h" // FIXUP First for QHULL_USES_QT
+
+#include "libqhullcpp/QhullVertexSet.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/RboxPoints.h"
-#include "Qhull.h"
-#include "QhullError.h"
-#include "QhullFacet.h"
-#include "QhullFacetSet.h"
using std::cout;
using std::endl;
using std::ostringstream;
using std::ostream;
using std::string;
namespace orgQhull {
-class QhullFacetSet_test : public RoadTest
+class QhullVertexSet_test : public RoadTest
{
Q_OBJECT
-#//Test slots
+#//!\name Test slots
private slots:
void cleanup();
void t_construct();
void t_convert();
void t_readonly();
void t_foreach();
void t_io();
-};//QhullFacetSet_test
+};//QhullVertexSet_test
void
-add_QhullFacetSet_test()
+add_QhullVertexSet_test()
{
- new QhullFacetSet_test();
+ new QhullVertexSet_test();
}
//Executed after each testcase
-void QhullFacetSet_test::
+void QhullVertexSet_test::
cleanup()
{
RoadTest::cleanup();
- UsingQhullLib::checkQhullMemoryEmpty();
}
-void QhullFacetSet_test::
+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();
- QhullFacetSet fs2= f.neighborFacets();
- QVERIFY(!fs2.isEmpty());
- QCOMPARE(fs2.count(),4);
- QhullFacetSet fs4= fs2; // copy constructor
- QVERIFY(fs4==fs2);
- QhullFacetSet fs3(q.qhullQh()->facet_mergeset);
- QVERIFY(fs3.isEmpty());
+ 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());
+ q.checkAndFreeQhullMemory();
}//t_construct
-void QhullFacetSet_test::
+void QhullVertexSet_test::
t_convert()
{
RboxPoints rcube("c");
- Qhull q(rcube,"QR0 QV2"); // rotated unit cube
+ 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();
- QhullFacetSet fs2= f.neighborFacets();
- QVERIFY(!fs2.isSelectAll());
- QCOMPARE(fs2.count(),2);
- std::vector<QhullFacet> fv= fs2.toStdVector();
- QCOMPARE(fv.size(), 2u);
- QList<QhullFacet> fv2= fs2.toQList();
- QCOMPARE(fv2.size(), 2);
- fs2.selectAll();
- QVERIFY(fs2.isSelectAll());
- std::vector<QhullFacet> fv3= fs2.toStdVector();
+ QhullVertexSet vs2= f.vertices();
+ QCOMPARE(vs2.count(),4);
+ std::vector<QhullVertex> fv= vs2.toStdVector();
+ QCOMPARE(fv.size(), 4u);
+ QList<QhullVertex> fv2= vs2.toQList();
+ QCOMPARE(fv2.size(), 4);
+ std::vector<QhullVertex> fv3= vs2.toStdVector();
QCOMPARE(fv3.size(), 4u);
- QList<QhullFacet> fv4= fs2.toQList();
+ QList<QhullVertex> fv4= vs2.toQList();
QCOMPARE(fv4.size(), 4);
+ q.checkAndFreeQhullMemory();
}//t_convert
//! Spot check properties and read-only. See QhullSet_test
-void QhullFacetSet_test::
+void QhullVertexSet_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));
+ 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));
+ q.checkAndFreeQhullMemory();
}//t_readonly
-void QhullFacetSet_test::
+void QhullVertexSet_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)){
- f= f.next();
- }
- QVERIFY(fs.contains(f));
- QCOMPARE(fs.first(), *fs.begin());
- QCOMPARE(*(fs.end()-1), fs.last());
+ 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());
+ q.checkAndFreeQhullMemory();
}//t_foreach
-void QhullFacetSet_test::
+void QhullVertexSet_test::
t_io()
{
RboxPoints rcube("c");
{
Qhull q(rcube,"QR0 QV0"); // good facets are adjacent to point 0
- QhullFacetSet fs= q.firstFacet().neighborFacets();
+ cout << "INFO : Cube rotated by QR" << q.rotateRandom() << std::endl;
+ QhullVertexSet vs= q.firstFacet().vertices();
ostringstream os;
- os << fs.print(q.runId(), "Neighbors of first facet with point 0");
- os << fs.printIdentifiers("\nFacet identifiers: ");
+ os << vs.print("Vertices of first facet with point 0");
+ os << vs.printIdentifiers("\nVertex identifiers: ");
cout<< os.str();
- QString facets= QString::fromStdString(os.str());
- QCOMPARE(facets.count(QRegExp(" f[0-9]")), 2+13*2);
+ QString vertices= QString::fromStdString(os.str());
+ QCOMPARE(vertices.count(QRegExp(" v[0-9]")), 4);
+ q.checkAndFreeQhullMemory();
}
}//t_io
-//FIXUP -- Move conditional, QhullFacetSet code to QhullFacetSet.cpp
+//FIXUP -- Move conditional, QhullVertexSet code to QhullVertexSet.cpp
#ifndef QHULL_NO_STL
-std::vector<QhullFacet> QhullFacetSet::
+std::vector<QhullVertex> QhullVertexSet::
toStdVector() const
{
- QhullSetIterator<QhullFacet> i(*this);
- std::vector<QhullFacet> vs;
+ QhullSetIterator<QhullVertex> i(*this);
+ std::vector<QhullVertex> vs;
while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.push_back(f);
- }
+ QhullVertex v= i.next();
+ vs.push_back(v);
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
-QList<QhullFacet> QhullFacetSet::
+QList<QhullVertex> QhullVertexSet::
toQList() const
{
- QhullSetIterator<QhullFacet> i(*this);
- QList<QhullFacet> vs;
+ QhullSetIterator<QhullVertex> i(*this);
+ QList<QhullVertex> vs;
while(i.hasNext()){
- QhullFacet f= i.next();
- if(isSelectAll() || f.isGood()){
- vs.append(f);
- }
+ QhullVertex v= i.next();
+ vs.append(v);
}
return vs;
}//toQList
#endif //QHULL_USES_QT
}//orgQhull
-#include "moc/QhullFacetSet_test.moc"
+#include "moc/QhullVertexSet_test.moc"
diff --git a/src/qhulltest/QhullVertex_test.cpp b/src/qhulltest/QhullVertex_test.cpp
index 019def9..53cd529 100644
--- a/src/qhulltest/QhullVertex_test.cpp
+++ b/src/qhulltest/QhullVertex_test.cpp
@@ -1,188 +1,188 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/QhullVertex_test.cpp#9 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/QhullVertex_test.cpp#12 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include "RoadTest.h"
-#include "QhullVertex.h"
-#include "Coordinates.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacet.h"
-#include "QhullFacetSet.h"
-#include "QhullVertexSet.h"
-#include "Qhull.h"
+#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
-#//Test slots
+#//!\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();
}
//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
- QhullVertex v;
- QVERIFY(!v.isDefined());
- QCOMPARE(v.dimension(),0);
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.isDefined());
+ QVERIFY(v.isValid());
QCOMPARE(v.dimension(),3);
QhullVertex v5= v2; // copy constructor
QVERIFY(v5==v2);
QVERIFY(v5==v);
- QhullVertex v3= v2.getVertexT();
+ QhullVertex v3(q, v2.getVertexT());
QCOMPARE(v,v3);
- QhullVertex v4= v2.getBaseT();
+ QhullVertex v4(q, v2.getBaseT());
QCOMPARE(v,v4);
q.checkAndFreeQhullMemory();
}//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.isDefined());
+ 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());
}
- QhullVertexListIterator i2(i);
- QEXPECT_FAIL("", "ListIterator copy constructor not reset to BOT", Continue);
- QVERIFY(!i2.hasPrevious());
// test point()
foreach (QhullVertex v, q.vertexList()){ // Qt only
QhullPoint p= v.point();
int j= p.id();
- cout << "Point " << j << ":\n" << p.print() << endl;
+ cout << "Point " << j << ":\n" << p << endl;
QVERIFY(j>=0 && j<8);
}
q.checkAndFreeQhullMemory();
}
}//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));
}
}
q.checkAndFreeQhullMemory();
}
}//t_foreach
void QhullVertex_test::
t_io()
{
RboxPoints rcube("c");
{
Qhull q(rcube, "");
QhullVertex v= q.beginVertex();
ostringstream os;
- os << "Vertex and vertices w/o runId:\n";
+ os << "Vertex and vertices:\n";
os << v;
QhullVertexSet vs= q.firstFacet().vertices();
os << vs;
- os << "Vertex and vertices w/ FIXUP runId:\n";
- os << v.print();
- os << vs.print("vertices:");
+ 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);
q.checkAndFreeQhullMemory();
}
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);
q.checkAndFreeQhullMemory();
}
}//t_io
}//orgQhull
#include "moc/QhullVertex_test.moc"
diff --git a/src/qhulltest/Qhull_test.cpp b/src/qhulltest/Qhull_test.cpp
index 8b9d6df..e560fc6 100644
--- a/src/qhulltest/Qhull_test.cpp
+++ b/src/qhulltest/Qhull_test.cpp
@@ -1,389 +1,365 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/Qhull_test.cpp#8 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/Qhull_test.cpp#15 $$Change: 1879 $
+** $DateTime: 2015/04/18 08:36:07 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
-#include "RoadTest.h" // QT_VERSION
+#include "qhulltest/RoadTest.h" // QT_VERSION
-#include "Qhull.h"
-#include "QhullError.h"
-#include "RboxPoints.h"
-#include "QhullFacetList.h"
+#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
-#//Test slots
+#//!\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();
}
//Executed after each testcase
void Qhull_test::
cleanup()
{
RoadTest::cleanup();
}
void Qhull_test::
t_construct()
{
{
Qhull q;
QCOMPARE(q.dimension(),0);
- QVERIFY(q.qhullQh()!=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();
}
- Qhull q2(q); // Copy constructor and copy assignment OK if not q.initialized()
- QCOMPARE(q2.dimension(),0);
- q= q2;
- QCOMPARE(q.dimension(),0);
q.checkAndFreeQhullMemory();
- q2.checkAndFreeQhullMemory();
}
{
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);
- try{
- Qhull q2(q);
- QFAIL("Copy constructor did not fail for initialized Qhull.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- try{
- Qhull q3;
- q3= q;
- QFAIL("Copy assignment did not fail for initialized Qhull source.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- QCOMPARE(q.dimension(),3);
- try{
- Qhull q4;
- q= q4;
- QFAIL("Copy assignment did not fail for initialized Qhull destination.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- QCOMPARE(q.dimension(),3);
q.checkAndFreeQhullMemory();
}
{
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
q.checkAndFreeQhullMemory();
}
}//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;
- q.feasiblePoint << 0.0 << 0.0;
+ Coordinates feasible;
+ feasible << 0.0 << 0.0;
+ q.setFeasiblePoint(feasible);
Coordinates c(std::vector<double>(2, 0.0));
- QVERIFY(q.feasiblePoint==c);
+ 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 intersect\n";
+ cout << "Expecting summary of halfspace intersection\n";
q.outputQhull();
- q.useOutputStream= false;
+ q.qh()->disableOutputStream(); // Same as q.disableOutputStream()
cout << "Expecting no output from qh_fprintf() in Qhull.cpp\n";
q.outputQhull();
q.checkAndFreeQhullMemory();
}
}//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(""));
q.checkAndFreeQhullMemory();
}
{
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 QH11026 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());
q.checkAndFreeQhullMemory();
}
{
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::fromAscii(s).left(6), QString("QH6023"));
+ QCOMPARE(QString::fromLatin1(s).left(6), QString("QH6023"));
}
//FIXUP QH11026 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());
q.checkAndFreeQhullMemory();
}
{
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::fromAscii(s).left(6), QString("QH6029"));
+ QCOMPARE(QString::fromLatin1(s).left(6), QString("QH6029"));
}
//FIXUP QH11026 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());
q.checkAndFreeQhullMemory();
}
}//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();
q.checkAndFreeQhullMemory();
}
{
Qhull q;
q.runQhull(rcube, "");
q.setOutputStream(&cout);
q.outputQhull();
q.checkAndFreeQhullMemory();
}
}//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.qhullQh()->ALLpoints, 0u);
- QCOMPARE(q.qhullQh()->GOODpoint, 0);
- QCOMPARE(q.qhullQh()->IStracing, 0);
- QCOMPARE(q.qhullQh()->MAXcoplanar+1.0, 1.0); // fuzzy compare
- QCOMPARE(q.qhullQh()->MERGING, 1u);
- QCOMPARE(q.qhullQh()->input_dim, 3);
- QCOMPARE(QString(q.qhullQh()->qhull_options).left(8), QString(" run-id"));
- QCOMPARE(q.qhullQh()->num_facets, 6);
- QCOMPARE(q.qhullQh()->hasTriangulation, 0u);
- QCOMPARE(q.qhullQh()->max_outside - q.qhullQh()->min_vertex + 1.0, 1.0); // fuzzy compare
- QCOMPARE(*q.qhullQh()->gm_matrix+1.0, 1.0); // fuzzy compare
+ 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
q.checkAndFreeQhullMemory();
}
}//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);
q.checkAndFreeQhullMemory();
}
}//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);
q.checkAndFreeQhullMemory();
}
}//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.
q.checkAndFreeQhullMemory();
}//t_modify
}//orgQhull
// Redefine Qhull's usermem.c
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_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/qhulltest/RboxPoints_test.cpp b/src/qhulltest/RboxPoints_test.cpp
index 4822da3..fc685dc 100644
--- a/src/qhulltest/RboxPoints_test.cpp
+++ b/src/qhulltest/RboxPoints_test.cpp
@@ -1,216 +1,214 @@
/****************************************************************************
**
** Copyright (c) 2006-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/RboxPoints_test.cpp#6 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/RboxPoints_test.cpp#10 $$Change: 1868 $
+** $DateTime: 2015/03/26 20:13:15 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include "RoadTest.h" // QT_VERSION
-#include "RboxPoints.h"
-#include "QhullError.h"
+#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
-#//Test slots
+#//!\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();
}
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);
- 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(2);
+ 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<rp.endCoordinates()){
QVERIFY(++ci<rp.endCoordinates());
QCOMPARE(*cci, *ci);
i++;
}
QVERIFY(++ci==rp.endCoordinates());
QCOMPARE(i, 8*3);
orgQhull::Coordinates::Iterator ci4= rp.beginCoordinates(4);
QCOMPARE(rp.endCoordinates()-ci4, 4*3);
orgQhull::Coordinates::ConstIterator cci4= rp.beginCoordinates(4);
orgQhull::Coordinates::ConstIterator cci5= rp.endCoordinates();
QCOMPARE(cci5-cci4, 4*3);
}//t_foreach
void RboxPoints_test::
t_change()
{
RboxPoints rp("c D2");
stringstream s;
s << "4 count" << endl;
s << "2 dimension" << endl;
s << "1 2 3 4 5 6 7 8" << endl;
rp.appendPoints(s);
QCOMPARE(rp.count(), 8);
orgQhull::Coordinates::Iterator ci= rp.beginCoordinates(7);
QCOMPARE(*ci, 7.0);
try{
stringstream s2;
s2 << "4 count" << endl;
s2 << "2 dimension" << endl;
s2 << "1 2 3 4 5 6 7 " << endl;
rp.appendPoints(s2);
QFAIL("incomplete appendPoints() did not fail.");
}catch (const std::exception &e) {
cout << "INFO : Caught " << e.what();
}
RboxPoints rp2;
rp2.append(rp);
QCOMPARE(rp2.count(), 8);
orgQhull::Coordinates::ConstIterator cci2= rp2.beginCoordinates(6);
QCOMPARE(*(cci2+1), 6.0);
rp2.appendPoints("D2 10 P0");
QCOMPARE(rp2.count(), 19);
orgQhull::Coordinates::ConstIterator cie= rp2.beginCoordinates(8);
QCOMPARE(*cie, 0.0);
RboxPoints rp3;
coordT points[] = { 0, 1,1,0,1,1,0,0};
rp3.setDimension(2);
rp3.append(8,points);
QCOMPARE(rp3.count(), 4);
orgQhull::Coordinates::Iterator ci3= rp3.beginCoordinates(3);
QCOMPARE(*ci3, 0.0);
}//t_change
void RboxPoints_test::
t_ostream()
{
RboxPoints rp("c D2");
ostringstream oss;
oss << rp;
string s= oss.str();
QString qs= QString::fromStdString(s);
QCOMPARE(qs.count("-0.5"), 4);
}//t_ostream
}//orgQhull
#include "moc/RboxPoints_test.moc"
diff --git a/src/qhulltest/RoadTest.cpp b/src/qhulltest/RoadTest.cpp
index cd6934a..bb75543 100644
--- a/src/qhulltest/RoadTest.cpp
+++ b/src/qhulltest/RoadTest.cpp
@@ -1,84 +1,84 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/RoadTest.cpp#3 $$Change: 1810 $
-** $Date: 2015/01/17 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/RoadTest.cpp#4 $$Change: 1868 $
+** $Date: 2015/03/26 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include <stdexcept>
#include "RoadTest.h"
using std::cout;
using std::endl;
namespace orgQhull {
-#//class variable
+#//!\name class variable
QList<RoadTest*> RoadTest::
s_testcases;
int RoadTest::
s_test_count= 0;
int RoadTest::
s_test_fail= 0;
QStringList RoadTest::
s_failed_tests;
-#//Slot
+#//!\name Slot
//! Executed after each test
void RoadTest::
cleanup()
{
s_test_count++;
if(QTest::currentTestFailed()){
recordFailedTest();
}
}//cleanup
-#//Helper
+#//!\name Helper
void RoadTest::
recordFailedTest()
{
s_test_fail++;
QString className= metaObject()->className();
s_failed_tests << className + "::" + QTest::currentTestFunction();
}
-#//class function
+#//!\name class function
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/qhulltest/RoadTest.h b/src/qhulltest/RoadTest.h
index df3bdf3..4c99b1a 100644
--- a/src/qhulltest/RoadTest.h
+++ b/src/qhulltest/RoadTest.h
@@ -1,101 +1,101 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/RoadTest.h#3 $$Change: 1810 $
-** $Date: 2015/01/17 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/RoadTest.h#4 $$Change: 1868 $
+** $Date: 2015/03/26 $$Author: bbarber $
**
****************************************************************************/
#ifndef ROADTEST_H
#define ROADTEST_H
//pre-compiled with RoadTest.h
#include <QObject> // Qt C++ Framework
#include <QtTest/QtTest>
#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
-#//Test slot
+#//!\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();
}
Send additional output to cout
*/
class RoadTest : public QObject
{
Q_OBJECT
#//!\name Class globals
protected:
static QList<RoadTest *>
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); }
~RoadTest() { s_testcases.removeAll(this); }
-#//Helper
+#//!\name Helper
void recordFailedTest();
#//!\name Class functions
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/qhulltest/UsingLibQhull_test.cpp b/src/qhulltest/UsingLibQhull_test.cpp
deleted file mode 100644
index a4e49ed..0000000
--- a/src/qhulltest/UsingLibQhull_test.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/UsingLibQhull_test.cpp#7 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
-**
-****************************************************************************/
-
-//pre-compiled headers
-#include <iostream>
-#include "RoadTest.h" // QT_VERSION
-
-#include "UsingLibQhull.h"
-#include "QhullError.h"
-#include "Qhull.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 UsingLibQhull_test : public RoadTest
-{
- Q_OBJECT
-
-#//Test slots
-private slots:
- void cleanup();
- void t_classMembers();
- void t_globalPoints();
- void t_UsingLibQhull();
- void t_methods();
- void t_cleanuptestcase();
-};//UsingLibQhull_test
-
-void
-add_UsingLibQhull_test()
-{
- new UsingLibQhull_test();
-}
-
-//Executed after each testcase
-void UsingLibQhull_test::
-cleanup()
-{
- UsingLibQhull::checkQhullMemoryEmpty();
- RoadTest::cleanup();
-}
-
-void UsingLibQhull_test::
-t_classMembers()
-{
- {
- //checkQhullMemoryEmpty tested by cleanup()
- QCOMPARE(UsingLibQhull::globalMachineEpsilon()+1.0, 1.0);
- RboxPoints r10("10");
- Qhull q(r10,"v"); // voronoi diagram of 10 points
- UsingLibQhull::unsetGlobalAngleEpsilon();
- UsingLibQhull::unsetGlobalDistanceEpsilon();
- cout << "MachineEpsilon " << UsingLibQhull::globalMachineEpsilon()
- << " angleEpsilon " << UsingLibQhull::globalAngleEpsilon()
- << " distanceEpsilon " << UsingLibQhull::globalDistanceEpsilon()
- << endl;
- QCOMPARE(UsingLibQhull::currentAngleEpsilon()+1.0, 1.0);
- QVERIFY(UsingLibQhull::currentAngleEpsilon() > UsingLibQhull::globalMachineEpsilon());
- QCOMPARE(UsingLibQhull::currentDistanceEpsilon()+1.0, 1.0);
- QVERIFY(UsingLibQhull::currentDistanceEpsilon() >= UsingLibQhull::currentAngleEpsilon());
- QCOMPARE(UsingLibQhull::globalAngleEpsilon()+1.0, UsingLibQhull::currentAngleEpsilon()+1.0);
- QCOMPARE(UsingLibQhull::currentVertexDimension(), q.dimension());
- QCOMPARE(UsingLibQhull::globalDistanceEpsilon()+1.0, UsingLibQhull::currentDistanceEpsilon()+1.0);
- UsingLibQhull::setGlobalAngleEpsilon(1.0);
- UsingLibQhull::setGlobalDistanceEpsilon(1.0);
- cout << " Global angleEpsilon " << UsingLibQhull::globalAngleEpsilon()
- << " distanceEpsilon " << UsingLibQhull::globalDistanceEpsilon()
- << endl;
- QCOMPARE(UsingLibQhull::globalAngleEpsilon(), UsingLibQhull::globalDistanceEpsilon());
- QVERIFY(UsingLibQhull::currentAngleEpsilon() != UsingLibQhull::globalAngleEpsilon());
- UsingLibQhull::setGlobalVertexDimension(3);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), UsingLibQhull::currentVertexDimension());
- UsingLibQhull::setGlobalVertexDimension(2);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), 2);
- QCOMPARE(UsingLibQhull::currentVertexDimension(), q.dimension());
- QVERIFY(UsingLibQhull::currentDistanceEpsilon() != UsingLibQhull::globalDistanceEpsilon());
- UsingLibQhull::unsetGlobalAngleEpsilon();
- UsingLibQhull::unsetGlobalVertexDimension();
- UsingLibQhull::unsetGlobalDistanceEpsilon();
- QCOMPARE(UsingLibQhull::currentAngleEpsilon()+1.0, UsingLibQhull::globalAngleEpsilon()+1.0);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), UsingLibQhull::currentVertexDimension());
- QCOMPARE(UsingLibQhull::currentDistanceEpsilon()+1.0, UsingLibQhull::globalDistanceEpsilon()+1.0);
- UsingLibQhull::setGlobals();
- }
- QCOMPARE(UsingLibQhull::globalAngleEpsilon()+1.0, 1.0);
- QCOMPARE(UsingLibQhull::globalVertexDimension(), 4); // 'v'. VertexDimension is only used for QhullVertex where dim>15
- QCOMPARE(UsingLibQhull::globalDistanceEpsilon()+1.0, 1.0);
- UsingLibQhull::unsetGlobals();
- try{
- cout << UsingLibQhull::globalVertexDimension();
- QFAIL("Did not throw error for undefined dimension.");
- }catch(const std::exception &e){
- cout << "INFO Caught error -- " << e.what() << endl;
- }
-}//t_classMembers
-
-void UsingLibQhull_test::
-t_globalPoints()
-{
- const coordT *r10PointsBegin;
- {
- RboxPoints r10("10");
- Qhull q(r10,"v"); // voronoi diagram of 10 points
- UsingLibQhull::unsetGlobalPoints();
- int dimension;
- const coordT *pointsEnd;
- const coordT *pointsBegin= UsingLibQhull::globalPoints(&dimension, &pointsEnd);
- cout << "pointsBegin " << pointsBegin
- << " pointsEnd " << pointsEnd
- << " dimension " << dimension
- << endl;
- int dimension2;
- const coordT *pointsEnd2;
- const coordT *pointsBegin2= UsingLibQhull::currentPoints(&dimension2, &pointsEnd2);
- QCOMPARE(pointsBegin2, pointsBegin);
- QCOMPARE(pointsEnd2, pointsEnd);
- QCOMPARE(dimension2, dimension);
- coordT c[]= { 1.0,2.0, 3.0,4.0, 5.0,6.0 };
- UsingLibQhull::setGlobalPoints(2, c, c+3*2);
- pointsBegin= UsingLibQhull::globalPoints(&dimension, &pointsEnd);
- QCOMPARE(pointsBegin, c);
- QCOMPARE(pointsEnd[-1], 6.0);
- QCOMPARE(dimension, 2);
- UsingLibQhull::unsetGlobalPoints();
- pointsBegin= UsingLibQhull::globalPoints(&dimension, &pointsEnd);
- QCOMPARE(pointsBegin, pointsBegin2);
- QCOMPARE(pointsEnd, pointsEnd2);
- QCOMPARE(dimension, dimension2);
- UsingLibQhull::setGlobals();
- r10PointsBegin= pointsBegin;
- }
- int dimension3;
- const coordT *pointsEnd3;
- const coordT *pointsBegin3= UsingLibQhull::currentPoints(&dimension3, &pointsEnd3);
- QCOMPARE(pointsBegin3, r10PointsBegin); // Memory was freed
- QCOMPARE(pointsEnd3, r10PointsBegin+10*4);
- QCOMPARE(dimension3, 4);
- UsingLibQhull::unsetGlobals();
- try{
- pointsBegin3= UsingLibQhull::globalPoints(&dimension3, &pointsEnd3);
- QFAIL("Did not throw error for undefined global points.");
- }catch(const std::exception &e){
- cout << "INFO Caught error -- " << e.what() << endl;
- }
-}//t_globalPoints
-
-void UsingLibQhull_test::
-t_UsingLibQhull()
-{
- {
- Qhull q;
- UsingLibQhull uq(&q); // Normally created in a method using 'this'
-
- try{
- Qhull q2; // If qh_QHpointer, QhullQh() calls usinlibqhull()
- UsingLibQhull uq2(&q2);
- QFAIL("UsingLibQhull did not fail.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- }
- Qhull q3;
- UsingLibQhull uq3(&q3);
- // UsingLibQhull uq4; // Default constructors disabled.
-}//t_UsingLibQhull
-
-void UsingLibQhull_test::
-t_methods()
-{
- Qhull q;
- UsingLibQhull u(&q); // Normally created in a method using 'this'
- QVERIFY(u.defined());
- u.maybeThrowQhullMessage(0); // Nothing thrown
- try{
- u.maybeThrowQhullMessage(1);
- QFAIL("maybeThrowQhullMessage(1) did not fail.");
- }catch (const std::exception &e) {
- cout << "INFO : Caught " << e.what();
- }
- u.maybeThrowQhullMessage(2, UsingLibQhull::NOthrow);
- try{
- throw QhullError(10054, "Report previous NOthrow error");
- }catch (const std::exception &e) {
- cout << "INFO : " << e.what();
- }
-}//t_methods
-
-// Executed after last test
-void UsingLibQhull_test::
-t_cleanuptestcase()
-{
- UsingLibQhull::unsetGlobals();
-}//t_cleanuptestcase
-
-}//orgQhull
-
-#include "moc/UsingLibQhull_test.moc"
-
diff --git a/src/qhulltest/qhulltest.cpp b/src/qhulltest/qhulltest.cpp
index 80e8221..277dff6 100644
--- a/src/qhulltest/qhulltest.cpp
+++ b/src/qhulltest/qhulltest.cpp
@@ -1,87 +1,91 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
-** $Id: //main/2011/qhull/src/qhulltest/qhulltest.cpp#11 $$Change: 1810 $
-** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+** $Id: //main/2011/qhull/src/qhulltest/qhulltest.cpp#19 $$Change: 1951 $
+** $DateTime: 2015/08/30 21:30:30 $$Author: bbarber $
**
****************************************************************************/
//pre-compiled headers
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
#include "RoadTest.h"
-#include "../libqhullcpp/RoadError.h"
+#include "libqhullcpp/RoadError.h"
+extern "C" {
+#include "libqhull_r/qhull_ra.h"
+}
using std::cout;
using std::endl;
namespace orgQhull {
void addQhullTests(QStringList &args)
{
- TESTadd_(add_QhullPointSet_test); //copy
- TESTadd_(add_QhullPoint_test); //copy
+ TESTadd_(add_QhullVertexSet_test); //copied from below
if(args.contains("--all")){
args.removeAll("--all");
// up-to-date
- /**FIXUP
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
+
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 with eg/q_test" << endl;
+ 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;
}
return status;
}
}//orgQhull
int main(int argc, char *argv[])
{
return orgQhull::main(argc, argv); // Needs RoadTest:: for TESTadd_() linkage
}
diff --git a/src/qhulltest/qhulltest.pro b/src/qhulltest/qhulltest.pro
index 53623e4..0da34d3 100644
--- a/src/qhulltest/qhulltest.pro
+++ b/src/qhulltest/qhulltest.pro
@@ -1,34 +1,36 @@
# -------------------------------------------------
# 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
-CONFIG += qtestlib
+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
-HEADERS += RoadTest.h
diff --git a/src/qvoronoi/qvoronoi.c b/src/qvoronoi/qvoronoi.c
index 09447b4..f0b0d80 100644
--- a/src/qvoronoi/qvoronoi.c
+++ b/src/qvoronoi/qvoronoi.c
@@ -1,313 +1,299 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull/mem.h"
+#include "libqhull/qset.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
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\
\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) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
main( argc, argv )
processes the command line, calls qhull() to do the work, and exits
design:
initializes data structures
reads points
finishes initialization
computes convex hull and other structures
checks the result
writes the output
frees memory
*/
int main(int argc, char *argv[]) {
int curlong, totlong; /* used !qh_NOmem */
int exitcode, numpoints, dim;
coordT *points;
boolT ismalloc;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
if (!exitcode) {
+ qh 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( True);
#else
qh_freeqhull( False);
qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/qvoronoi/qvoronoi.c b/src/qvoronoi/qvoronoi_r.c
similarity index 85%
copy from src/qvoronoi/qvoronoi.c
copy to src/qvoronoi/qvoronoi_r.c
index 09447b4..b5c8dad 100644
--- a/src/qvoronoi/qvoronoi.c
+++ b/src/qvoronoi/qvoronoi_r.c
@@ -1,313 +1,300 @@
/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
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 "libqhull_r/mem_r.h"
+#include "libqhull_r/qset_r.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
-#include "libqhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#elif __cplusplus
+#if __cplusplus
extern "C" {
int isatty(int);
}
#elif _MSC_VER
#include <io.h>
#define isatty _isatty
-int _isatty(int);
+/* 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
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt">-</a>
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\
";
/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt2">-</a>
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\
\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) */
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="prompt3">-</a>
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\
";
/*-<a href="../libqhull/qh-qhull.htm#TOC"
>-------------------------------</a><a name="main">-</a>
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;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= false;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK
if ((argc == 1) && isatty( 0 /*stdin*/)) {
fprintf(stdout, qh_prompt2, qh_version);
exit(qh_ERRnone);
}
if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompta, qh_version,
qh_promptb, qh_promptc, qh_promptd, qh_prompte);
exit(qh_ERRnone);
}
if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
fprintf(stdout, qh_prompt3, qh_version);
exit(qh_ERRnone);
}
- qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
- exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ 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_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);
+ 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("_merge-exact", NULL, NULL);
- qh MERGEexact= True; /* 'Qx' always */
+ qh_option(qh, "_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();
+ 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 */
+ qh->NOerrexit= True; /* no more setjmp */
#ifdef qh_NOmem
- qh_freeqhull( True);
+ qh_freeqhull(qh, True);
#else
- qh_freeqhull( False);
- qh_memfreeshort(&curlong, &totlong);
+ qh_freeqhull(qh, False);
+ qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong)
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
totlong, curlong);
#endif
return exitcode;
} /* main */
diff --git a/src/rbox/rbox.c b/src/rbox/rbox.c
index 4a3d994..91c3b85 100644
--- a/src/rbox/rbox.c
+++ b/src/rbox/rbox.c
@@ -1,101 +1,87 @@
/*<html><pre> -<a href="../libqhull/index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
rbox.c
rbox program for generating input points for qhull.
notes:
50 points generated for 'rbox D4'
*/
-#include "random.h"
-#include "libqhull.h"
+#include "libqhull/random.h"
+#include "libqhull/libqhull.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-
-#if __MWERKS__ && __POWERPC__
-#include <SIOUX.h>
-#include <Files.h>
-#include <console.h>
-#include <Desk.h>
-#endif
+#include <string.h>
#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: 2001/06/24\n\
+args (any order, space separated): Version: 2015/08/30\n\
3000 number of random points in cube, lens, spiral, sphere or grid\n\
D3 dimension 3-d\n\
c add a unit cube to the output ('c G2.0' sets size)\n\
d add a unit diamond to the output ('d G2.0' sets size)\n\
l generate a regular 3-d spiral\n\
r generate a regular polygon, ('r s Z1 G0.1' makes a cone)\n\
s generate cospherical points\n\
x generate random points in simplex, may use 'r' or 'Wn'\n\
y same as 'x', plus simplex\n\
Pn,m,r add point [n,m,r] first, pads with 0\n\
\n\
Ln lens distribution of radius n. Also 's', 'r', 'G', 'W'.\n\
Mn,m,r lattice(Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...\n\
'27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}. Try 'M3,4 z'.\n\
W0.1 random distribution within 0.1 of the cube's or sphere's surface\n\
Z0.5 s random points in a 0.5 disk projected to a sphere\n\
Z0.5 s G0.6 same as Z0.5 within a 0.6 gap\n\
\n\
Bn bounding box coordinates, default %2.2g\n\
h output as homogeneous coordinates for cdd\n\
n remove command line from the first line of output\n\
On offset coordinates by n\n\
t use time as the random number seed(default is command line)\n\
tn use n as the random number seed\n\
z print integer coordinates, default 'Bn' is %2.2g\n\
";
/*--------------------------------------------
-rbox- main procedure of rbox application
*/
int main(int argc, char **argv) {
char *command;
int command_size;
int return_status;
-#if __MWERKS__ && __POWERPC__
- char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
- SIOUXSettings.showstatusline= False;
- SIOUXSettings.tabspaces= 1;
- SIOUXSettings.rows= 40;
- if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/
- || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
- || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
- fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
- argc= ccommand(&argv);
-#endif
+ QHULL_LIB_CHECK_RBOX
if (argc == 1) {
printf(prompt, qh_DEFAULTbox, qh_DEFAULTzbox);
return 1;
}
+ if (argc == 2 && strcmp(argv[1], "D4")==0)
+ fprintf(stderr, "\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)) {
fprintf(stderr, "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 {
fprintf(stderr, "rbox error: insufficient memory for %d bytes\n", command_size);
return_status= qh_ERRmem;
}
return return_status;
}/*main*/
diff --git a/src/rbox/rbox.pro b/src/rbox/rbox.pro
index 173e5ae..6c21bdb 100644
--- a/src/rbox/rbox.pro
+++ b/src/rbox/rbox.pro
@@ -1,9 +1,9 @@
# -------------------------------------------------
-# rbox.pro -- Qt project for rbox.exe
+# rbox.pro -- Qt project for rbox.exe with libqhullstatic
# -------------------------------------------------
include(../qhull-app-c.pri)
TARGET = rbox
SOURCES += rbox.c
diff --git a/src/rboxr/rbox_r.c b/src/rbox/rbox_r.c
similarity index 78%
rename from src/rboxr/rbox_r.c
rename to src/rbox/rbox_r.c
index fc0f52d..8a0829f 100644
--- a/src/rboxr/rbox_r.c
+++ b/src/rbox/rbox_r.c
@@ -1,70 +1,76 @@
+
/*<html><pre> -<a href="../libqhull/index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
rbox.c
rbox program for generating input points for qhull.
notes:
50 points generated for 'rbox D4'
*/
-#include "libqhull_r.h"
+#include "libqhull_r/libqhull_r.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#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: 2001/06/24\n\
+args (any order, space separated): Version: 2015/08/30 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\
Pn,m,r add point [n,m,r] first, pads with 0\n\
\n\
Ln lens distribution of radius n. Also 's', 'r', 'G', 'W'.\n\
Mn,m,r lattice(Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...\n\
'27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}. Try 'M3,4 z'.\n\
W0.1 random distribution within 0.1 of the cube's or sphere's surface\n\
Z0.5 s random points in a 0.5 disk projected to a sphere\n\
Z0.5 s G0.6 same as Z0.5 within a 0.6 gap\n\
\n\
Bn bounding box coordinates, default %2.2g\n\
h output as homogeneous coordinates for cdd\n\
n remove command line from the first line of output\n\
On offset coordinates by n\n\
t use time as the random number seed(default is command line)\n\
tn use n as the random number seed\n\
z print integer coordinates, default 'Bn' is %2.2g\n\
";
/*--------------------------------------------
-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)
+ fprintf(stderr, "\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); /* sets qh->qhull_command */
- return_status= qh_rboxpoints(qh, qh->qhull_command);
+ 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/rboxr/rboxr.pro b/src/rboxr/rboxr.pro
deleted file mode 100644
index 59d16d9..0000000
--- a/src/rboxr/rboxr.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-# -------------------------------------------------
-# rboxr.pro -- Qt project for rboxr.exe
-# -------------------------------------------------
-
-include(../qhull-app-c_r.pri)
-
-TARGET = rboxr
-
-SOURCES += rbox_r.c
diff --git a/src/testqset/testqset.c b/src/testqset/testqset.c
index 4f632bd..76c9faf 100644
--- a/src/testqset/testqset.c
+++ b/src/testqset/testqset.c
@@ -1,879 +1,885 @@
/*<html><pre> -<a href="../libqhull/index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/testqset/testqset.c#5 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/testqset/testqset.c#11 $$Change: 1914 $
+ $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
*/
+#include "libqhull/qset.h"
+#include "libqhull/mem.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "qset.h"
-#include "mem.h"
-
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 usermem.h */
void qh_exit(int exitcode) {
exit(exitcode);
} /* exit */
void qh_free(void *mem) {
free(mem);
} /* free */
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */
void qh_errexit(int exitcode, void *f, void *r)
{
- f= r; /* unused */
+ (void)f; /* unused */
+ (void)r; /* unused */
qh_exit(exitcode);
}
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) {
fprintf(stderr, "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 */
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(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<numInts; i++){
(*intarray)[i] =i;
}
qh_meminit(stderr);
qh_meminitbuffers(tracelevel, qh_MEMalign, 4 /*sizes*/, qh_MEMbufsize,qh_MEMinitbuf);
qh_memsize(10);
qh_memsize(20);
qh_memsize(30);
qh_memsize(40);
qh_memsetup();
qh_fprintf(stderr, 8001, "SETelemsize is %d bytes for pointer-to-int\n", SETelemsize);
}/*setupMemmory*/
void testSetappendSettruncate(int numInts, int *intarray, int checkEvery)
{
setT *ints= qh_setnew(4);
int i, isCheck;
qh_fprintf(stderr, 8002, "\n\nTesting qh_setappend 0..%d. Test", numInts-1);
for(i= 0; i<numInts; i++){
isCheck= log_i(ints, "i", i, numInts, checkEvery);
qh_setappend(&ints, intarray+i);
if(isCheck){
checkSetContents("qh_setappend", ints, i+1, 0, -1, -1);
}
}
qh_fprintf(stderr, 8014, "\n\nTesting qh_settruncate %d and 0. Test", numInts/2);
if(numInts>=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<numInts; i++){
isCheck= log_i(ints, "i", i, numInts, checkEvery);
qh_setappend2ndlast(&ints, intarray+i);
if(isCheck){
checkSetContents("qh_setappend2ndlast", ints, i+2, 0, 0, -1);
}
}
qh_fprintf(stderr, 8015, "\n\nTesting SETtruncate_ %d and 0. Test", numInts/2);
if(numInts>=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;
+ int i,j,isCheck;
qh_fprintf(stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
for(j=1; j<numInts; j++){ /* size 0 not valid */
if(log_i(ints, "j", j, numInts, MAXint)){
for(i= qh_setsize(ints); i<j; i++){
qh_setappend(&ints, intarray+i);
}
checkSetContents("qh_setappend", ints, j, 0, -1, -1);
for(i= 0; i<j && i<100; i++){ /* otherwise too slow */
isCheck= log_i(ints, "", i, numInts, checkEvery);
+ (void)isCheck; /* unused */
qh_setdelnthsorted(ints, i);
qh_setaddnth(&ints, i, intarray+i);
if(checkEvery==1){
checkSetContents("qh_setdelnthsorted qh_setaddnth", ints, j, 0, -1, -1);
}
}
checkSetContents("qh_setdelnthsorted qh_setaddnth 2", ints, j, 0, -1, -1);
}
}
qh_setfree(&ints);
}/*testSetdelSetadd*/
void testSetappendSet(int numInts, int *intarray, int checkEvery)
{
setT *ints=qh_setnew(1);
setT *ints2;
int i,j,k;
qh_fprintf(stderr, 8016, "\n\nTesting qh_setappend_set 0..%d. Test", numInts-1);
for(j=0; j<numInts; j++){
if(log_i(ints, "j", j, numInts, numInts)){
for(i= qh_setsize(ints); i<j; i++){
qh_setappend(&ints, intarray+i);
}
if(checkEvery==1){
checkSetContents("qh_setappend", ints, j, 0, -1, -1);
}
ints2= qh_setnew(j==0 ? 0 : j-1); /* One less than needed */
for(i= 0; i<=j && i<=20; i++){ /* otherwise too slow */
if(log_i(ints, "", i, numInts, numInts)){
for(k= qh_setsize(ints2); k<i; k++){
qh_setappend(&ints2, intarray+k);
}
if(checkEvery==1){
checkSetContents("qh_setappend 2", ints2, i, 0, -1, -1);
}
qh_setappend_set(&ints, ints2);
checkSetContents("qh_setappend_set", ints, i+j, 0, (j==0 ? -1 : 0), -1);
qh_settruncate(ints, j);
if(checkEvery==1){
checkSetContents("qh_settruncate", ints, j, 0, -1, -1);
}
}
}
qh_setfree(&ints2);
}
}
qh_setfree(&ints);
}/*testSetappendSet*/
void testSetcompactCopy(int numInts, int *intarray, int checkEvery)
{
setT *ints= qh_setnew(20);
setT *ints2= NULL;
int i,j,k;
qh_fprintf(stderr, 8017, "\n\nTesting qh_setcompact and qh_setcopy 0..%d. Test", numInts-1);
for(j=0; j<numInts; j++){
if(log_i(ints, "j", j, numInts, checkEvery)){
for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
for(k= 0; k<i%7; k++){
qh_setappend(&ints, NULL);
}
qh_setappend(&ints, intarray+i);
}
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", ints2, j, 0, 0, -1);
qh_setcompact(ints);
checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
}
}
qh_setfree(&ints);
qh_setfree(&ints2);
}/*testSetcompactCopy*/
void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery)
{
setT *ints= qh_setnew(1);
setT *ints2= NULL;
int i,j;
qh_fprintf(stderr, 8018, "\n\nTesting qh_setdel*, qh_setaddsorted, and 0..%d. Test", numInts-1);
for(j=0; j<numInts; j++){
if(log_i(ints, "j", j, numInts, checkEvery)){
for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
qh_setaddsorted(&ints, intarray+i);
}
checkSetContents("qh_setaddsorted", ints, j, 0, 0, -1);
if(j>3){
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);
- /* FIXUP qh_setdelnth 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; j<numInts; j++){
if(log_i(ints, "j", j, numInts, checkEvery)){
n= qh_setsize(ints);
qh_setlarger(&ints);
checkSetContents("qh_setlarger", ints, n, 0, -1, -1);
for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
qh_setappend(&ints, intarray+i);
}
checkSetContents("qh_setappend", ints, j, 0, -1, -1);
if(!qh_setequal(ints, ints)){
qh_fprintf(stderr, 6300, "testSetequalInEtc: set not equal to itself at length %d\n", j);
error_count++;
}
if(j==0 && !qh_setequal(ints, ints2)){
qh_fprintf(stderr, 6323, "testSetequalInEtc: empty set not equal to null set\n");
error_count++;
}
if(j>0){
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; j<numInts; j++){
if(log_i(ints, "j", j, numInts, checkEvery)){
for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
if(!qh_setunique(&ints, intarray+i)){
qh_fprintf(stderr, 6340, "qh_setunique: not able to append next element %d\n", i);
error_count++;
}
if(checkEvery==1){
checkSetContents("qh_setunique", ints, i+1, 0, -1, -1);
}
if(qh_setunique(&ints, intarray+i)){
qh_fprintf(stderr, 6341, "qh_setunique: appended next element twice %d\n", i);
error_count++;
}
if(qh_setunique(&ints, intarray+i/2)){
qh_fprintf(stderr, 6346, "qh_setunique: appended middle element twice %d/2\n", i);
error_count++;
}
}
checkSetContents("qh_setunique 2", ints, j, 0, -1, -1);
if(j==0 && NULL!=qh_setlast(ints)){
qh_fprintf(stderr, 6339, "qh_setlast: returned last element of empty set\n");
error_count++;
}
if(j>0){
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; i<prepend; i++){
void **p= &SETelem_(ints2, i);
*p= intarray+0;
}
for(i= 0; i<prepend; i++){
qh_setdelnthsorted(ints2, 0); /* delete undefined prefix */
}
checkSetContents("qh_setnew_delnthsorted", ints2, j-1, 0, j/2+1, -1);
if(j>2){
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; j<numInts; j++){
if(log_i(ints, "j", j, numInts, checkEvery)){
if(j<20){
for(i=0; i<j; i++){
ints2= qh_settemp(j);
}
qh_settempfree_all();
}
for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
qh_setappend(&ints, intarray+i);
}
ints2= qh_settemp(j);
if(j>0){
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/testqset/testqset.pro b/src/testqset/testqset.pro
index b49c337..0ebc91e 100644
--- a/src/testqset/testqset.pro
+++ b/src/testqset/testqset.pro
@@ -1,29 +1,29 @@
# -------------------------------------------------
# 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 += ../libqhull
+INCLUDEPATH += ..
SOURCES += testqset.c
SOURCES += ../libqhull/qset.c
SOURCES += ../libqhull/mem.c
HEADERS += ../libqhull/mem.h
HEADERS += ../libqhull/qset.h
diff --git a/src/testqsetr/testqset_r.c b/src/testqset_r/testqset_r.c
similarity index 98%
rename from src/testqsetr/testqset_r.c
rename to src/testqset_r/testqset_r.c
index 8d3e569..2ffcb37 100644
--- a/src/testqsetr/testqset_r.c
+++ b/src/testqset_r/testqset_r.c
@@ -1,879 +1,885 @@
/*<html><pre> -<a href="../libqhull/index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
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/2011/qhull/src/testqsetr/testqset_r.c#3 $$Change: 1810 $
- $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
+ $Id: //main/2011/qhull/src/testqset_r/testqset_r.c#2 $$Change: 1914 $
+ $DateTime: 2015/06/21 22:08:19 $$Author: bbarber $
*/
+#include "libqhull_r/qset_r.h"
+#include "libqhull_r/mem_r.h"
+#include "libqhull_r/libqhull_r.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "../libqhullr/qset_r.h"
-#include "../libqhullr/mem_r.h"
-#include "../libqhullr/libqhull_r.h"
-
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[]= "testqsetr N [M] [T5] -- Test reentrant qset_r.c and mem_r.c\n\
+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\
- testqsetr 10000\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 usermem.h */
void qh_exit(int exitcode) {
exit(exitcode);
} /* exit */
void qh_free(void *mem) {
free(mem);
} /* free */
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */
void qh_errexit(qhT *qh, int exitcode, facetT *f, ridgeT *r)
{
- void *unused= f;
- unused= r;
- unused= qh;
+ (void)f; /* unused */
+ (void)r; /* unused */
+ (void)qh; /* unused */
qh_exit(exitcode);
}
void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... )
{
- static int needs_cr= 0; /* True if qh_fprintf needs a CR */
+ 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) {
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;
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: OK\n\n");
+ 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(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<numInts; i++){
(*intarray)[i] =i;
}
qh_meminit(qh, stderr);
qh_meminitbuffers(qh, tracelevel, qh_MEMalign, 4 /*sizes*/, qh_MEMbufsize, qh_MEMinitbuf);
qh_memsize(qh, 10);
qh_memsize(qh, 20);
qh_memsize(qh, 30);
qh_memsize(qh, 40);
qh_memsetup(qh);
qh_fprintf(qh, stderr, 8001, "SETelemsize is %d bytes for pointer-to-int\n", SETelemsize);
}/*setupMemmory*/
void testSetappendSettruncate(qhT *qh, int numInts, int *intarray, int checkEvery)
{
setT *ints= qh_setnew(qh, 4);
int i, isCheck;
qh_fprintf(qh, stderr, 8002, "\n\nTesting qh_setappend 0..%d. Test", numInts-1);
for(i= 0; i<numInts; i++){
isCheck= log_i(qh, ints, "i", i, numInts, checkEvery);
qh_setappend(qh, &ints, intarray+i);
if(isCheck){
checkSetContents(qh, "qh_setappend", ints, i+1, 0, -1, -1);
}
}
qh_fprintf(qh, stderr, 8014, "\n\nTesting qh_settruncate %d and 0. Test", numInts/2);
if(numInts>=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<numInts; i++){
isCheck= log_i(qh, ints, "i", i, numInts, checkEvery);
qh_setappend2ndlast(qh, &ints, intarray+i);
if(isCheck){
checkSetContents(qh, "qh_setappend2ndlast", ints, i+2, 0, 0, -1);
}
}
qh_fprintf(qh, stderr, 8015, "\n\nTesting SETtruncate_ %d and 0. Test", numInts/2);
if(numInts>=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;
+ int i,j,isCheck;
qh_fprintf(qh, stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
for(j=1; j<numInts; j++){ /* size 0 not valid */
if(log_i(qh, ints, "j", j, numInts, MAXint)){
for(i= qh_setsize(qh, ints); i<j; i++){
qh_setappend(qh, &ints, intarray+i);
}
checkSetContents(qh, "qh_setappend", ints, j, 0, -1, -1);
for(i= 0; i<j && i<100; i++){ /* otherwise too slow */
isCheck= log_i(qh, ints, "", i, numInts, checkEvery);
+ (void)isCheck; /* unused */
qh_setdelnthsorted(qh, ints, i);
qh_setaddnth(qh, &ints, i, intarray+i);
if(checkEvery==1){
checkSetContents(qh, "qh_setdelnthsorted qh_setaddnth", ints, j, 0, -1, -1);
}
}
checkSetContents(qh, "qh_setdelnthsorted qh_setaddnth 2", ints, j, 0, -1, -1);
}
}
qh_setfree(qh, &ints);
}/*testSetdelSetadd*/
void testSetappendSet(qhT *qh, int numInts, int *intarray, int checkEvery)
{
setT *ints=qh_setnew(qh, 1);
setT *ints2;
int i,j,k;
qh_fprintf(qh, stderr, 8016, "\n\nTesting qh_setappend_set 0..%d. Test", numInts-1);
for(j=0; j<numInts; j++){
if(log_i(qh, ints, "j", j, numInts, numInts)){
for(i= qh_setsize(qh, ints); i<j; i++){
qh_setappend(qh, &ints, intarray+i);
}
if(checkEvery==1){
checkSetContents(qh, "qh_setappend", ints, j, 0, -1, -1);
}
ints2= qh_setnew(qh, j==0 ? 0 : j-1); /* One less than needed */
for(i= 0; i<=j && i<=20; i++){ /* otherwise too slow */
if(log_i(qh, ints, "", i, numInts, numInts)){
for(k= qh_setsize(qh, ints2); k<i; k++){
qh_setappend(qh, &ints2, intarray+k);
}
if(checkEvery==1){
checkSetContents(qh, "qh_setappend 2", ints2, i, 0, -1, -1);
}
qh_setappend_set(qh, &ints, ints2);
checkSetContents(qh, "qh_setappend_set", ints, i+j, 0, (j==0 ? -1 : 0), -1);
qh_settruncate(qh, ints, j);
if(checkEvery==1){
checkSetContents(qh, "qh_settruncate", ints, j, 0, -1, -1);
}
}
}
qh_setfree(qh, &ints2);
}
}
qh_setfree(qh, &ints);
}/*testSetappendSet*/
void testSetcompactCopy(qhT *qh, int numInts, int *intarray, int checkEvery)
{
setT *ints= qh_setnew(qh, 20);
setT *ints2= NULL;
int i,j,k;
qh_fprintf(qh, stderr, 8017, "\n\nTesting qh_setcompact and qh_setcopy 0..%d. Test", numInts-1);
for(j=0; j<numInts; j++){
if(log_i(qh, ints, "j", j, numInts, checkEvery)){
for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
for(k= 0; k<i%7; k++){
qh_setappend(qh, &ints, NULL);
}
qh_setappend(qh, &ints, intarray+i);
}
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", ints2, j, 0, 0, -1);
qh_setcompact(qh, ints);
checkSetContents(qh, "qh_setcompact", ints, j, 0, 0, -1);
}
}
qh_setfree(qh, &ints);
qh_setfree(qh, &ints2);
}/*testSetcompactCopy*/
void testSetdelsortedEtc(qhT *qh, int numInts, int *intarray, int checkEvery)
{
setT *ints= qh_setnew(qh, 1);
setT *ints2= NULL;
int i,j;
qh_fprintf(qh, stderr, 8018, "\n\nTesting qh_setdel*, qh_setaddsorted, and 0..%d. Test", numInts-1);
for(j=0; j<numInts; j++){
if(log_i(qh, ints, "j", j, numInts, checkEvery)){
for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
qh_setaddsorted(qh, &ints, intarray+i);
}
checkSetContents(qh, "qh_setaddsorted", ints, j, 0, 0, -1);
if(j>3){
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);
/* FIXUP qh_setdelnth 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; j<numInts; j++){
if(log_i(qh, ints, "j", j, numInts, checkEvery)){
n= qh_setsize(qh, ints);
qh_setlarger(qh, &ints);
checkSetContents(qh, "qh_setlarger", ints, n, 0, -1, -1);
for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
qh_setappend(qh, &ints, intarray+i);
}
checkSetContents(qh, "qh_setappend", ints, j, 0, -1, -1);
if(!qh_setequal(ints, ints)){
qh_fprintf(qh, stderr, 6300, "testSetequalInEtc: set not equal to itself at length %d\n", j);
error_count++;
}
if(j==0 && !qh_setequal(ints, ints2)){
qh_fprintf(qh, stderr, 6323, "testSetequalInEtc: empty set not equal to null set\n");
error_count++;
}
if(j>0){
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; j<numInts; j++){
if(log_i(qh, ints, "j", j, numInts, checkEvery)){
for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
if(!qh_setunique(qh, &ints, intarray+i)){
qh_fprintf(qh, stderr, 6340, "qh_setunique: not able to append next element %d\n", i);
error_count++;
}
if(checkEvery==1){
checkSetContents(qh, "qh_setunique", ints, i+1, 0, -1, -1);
}
if(qh_setunique(qh, &ints, intarray+i)){
qh_fprintf(qh, stderr, 6341, "qh_setunique: appended next element twice %d\n", i);
error_count++;
}
if(qh_setunique(qh, &ints, intarray+i/2)){
qh_fprintf(qh, stderr, 6346, "qh_setunique: appended middle element twice %d/2\n", i);
error_count++;
}
}
checkSetContents(qh, "qh_setunique 2", ints, j, 0, -1, -1);
if(j==0 && NULL!=qh_setlast(ints)){
qh_fprintf(qh, stderr, 6339, "qh_setlast: returned last element of empty set\n");
error_count++;
}
if(j>0){
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; i<prepend; i++){
void **p= &SETelem_(ints2, i);
*p= intarray+0;
}
for(i= 0; i<prepend; i++){
qh_setdelnthsorted(qh, ints2, 0); /* delete undefined prefix */
}
checkSetContents(qh, "qh_setnew_delnthsorted", ints2, j-1, 0, j/2+1, -1);
if(j>2){
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; j<numInts; j++){
if(log_i(qh, ints, "j", j, numInts, checkEvery)){
if(j<20){
for(i=0; i<j; i++){
ints2= qh_settemp(qh, j);
}
qh_settempfree_all(qh);
}
for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
qh_setappend(qh, &ints, intarray+i);
}
ints2= qh_settemp(qh, j);
if(j>0){
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/testqsetr/testqsetr.pro b/src/testqset_r/testqset_r.pro
similarity index 64%
rename from src/testqsetr/testqsetr.pro
rename to src/testqset_r/testqset_r.pro
index 9dbd10d..9cc2345 100644
--- a/src/testqsetr/testqsetr.pro
+++ b/src/testqset_r/testqset_r.pro
@@ -1,29 +1,29 @@
# -------------------------------------------------
-# testqset.pro -- Qt project file for testqset.exe
+# testqset_r.pro -- Qt project file for testqset_r.exe
# -------------------------------------------------
include(../qhull-warn.pri)
-TARGET = testqsetr
+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 += ../libqhullr
+INCLUDEPATH += ..
SOURCES += testqset_r.c
-SOURCES += ../libqhullr/qset_r.c
-SOURCES += ../libqhullr/mem_r.c
+SOURCES += ../libqhull_r/qset_r.c
+SOURCES += ../libqhull_r/mem_r.c
-HEADERS += ../libqhullr/mem_r.h
-HEADERS += ../libqhullr/qset_r.h
+HEADERS += ../libqhull_r/mem_r.h
+HEADERS += ../libqhull_r/qset_r.h
diff --git a/src/user_eg/user_eg.c b/src/user_eg/user_eg.c
index 1867143..41251b4 100644
--- a/src/user_eg/user_eg.c
+++ b/src/user_eg/user_eg.c
@@ -1,317 +1,330 @@
/*<html><pre> -<a href="../libqhull/qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
user_eg.c
- sample code for calling qhull() from an application. Uses reentrant libqhull_r
+ 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.cpp
+ 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 user_eg'
+ compiled by 'make bin/user_eg'
see libqhull.h for data structures, macros, and user-callable functions.
*/
#define qh_QHimport
-#include "qhull_r.h"
+#include "qhull_a.h"
/*-------------------------------------------------
-internal function prototypes
*/
-void print_summary(qhT *qh);
+void print_summary(void);
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 makeDelaunay(coordT *points, int numpoints, int dim, int seed);
+void findDelaunay(int dim);
void makehalf(coordT *points, int numpoints, int dim);
/*-------------------------------------------------
--print_summary(qh)
+-print_summary()
*/
-void print_summary(qhT *qh) {
+void print_summary(void) {
facetT *facet;
int k;
printf("\n%d vertices and %d facets with normals:\n",
- qh->num_vertices, qh->num_facets);
+ qh num_vertices, qh num_facets);
FORALLfacets {
- for (k=0; k < qh->hull_dim; k++)
+ 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; j<numpoints; j++) {
point= points + j*dim;
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makecube.*/
/*--------------------------------------------------
-makeDelaunay- set points for dim Delaunay triangulation of random points
points is numpoints X dim.
notes:
makeDelaunay() in user_eg2.c uses qh_setdelaunay() to project points in place.
*/
-void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim, int seed) {
+void makeDelaunay(coordT *points, int numpoints, int dim, int seed) {
int j,k;
coordT *point, realr;
printf("seed: %d\n", seed);
- qh_RANDOMseed_(qh, seed);
+ qh_RANDOMseed_( seed);
for (j=0; j<numpoints; j++) {
point= points + j*dim;
for (k= 0; k < dim; k++) {
realr= qh_RANDOMint;
point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
}
}
} /*.makeDelaunay.*/
/*--------------------------------------------------
-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 <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
*/
-void findDelaunay(qhT *qh, int dim) {
+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(qh, dim+1, 1, point);
- facet= qh_findbestfacet(qh, point, qh_ALL, &bestdist, &isoutside);
+ 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, qh_ERRqhull, facet, NULL);
+ 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<numpoints; j++) {
point= points + j*(dim+1);
point[dim]= -1.0; /* offset */
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makehalf.*/
#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
#define SIZEcube (1<<DIM)
#define SIZEdiamond (2*DIM)
#define TOTpoints (SIZEcube + SIZEdiamond)
/*--------------------------------------------------
-main- derived from call_qhull in user.c
see program header
this contains three runs of Qhull for convex hull, Delaunay
triangulation or Voronoi vertices, and halfspace intersection
*/
int main(int argc, char *argv[]) {
int dim= DIM; /* dimension of points */
int numpoints; /* number of points */
coordT points[(DIM+1)*TOTpoints]; /* array of coordinates for each point */
coordT *rows[TOTpoints];
boolT ismalloc= False; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[250]; /* option flags for qhull, see qh-quick.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 */
int i;
- qhT qh_qh;
- qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK
printf("This is the output from user_eg.c\n\n\
It shows how qhull() may be called from an application using the qhull\n\
-reentrant library. It is not part of qhull itself. If it appears accidently,\n\
-please remove user_eg.c from your project.\n\n");
+shared library. user_eg is not part of qhull itself. If it appears\n\
+accidently, please remove user_eg.c from your project. If it fails\n\
+immediately, user_eg.c was incorrectly linked to the reentrant library.\n\
+Also try 'user_eg T1 2>&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(qh, outfile, "input", rows, numpoints, dim);
- exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
+ 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(qh);
+ /* 'qh facet_list' contains the convex hull */
+ print_summary();
FORALLfacets {
/* ... your code ... */
}
}
- qh_freeqhull(qh, !qh_ALL); /* free long memory */
- qh_memfreeshort(qh, &curlong, &totlong); /* free short memory and memory allocator */
+ 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(qh, points, numpoints, dim, (int)time(NULL));
+ makeDelaunay(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,
+ 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 */
+ /* '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);
+ print_summary();
FORALLfacets {
/* ... your code ... */
}
printf( "\nfind %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim);
- exitcode= setjmp(qh->errexit);
+ 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= False;
+ findDelaunay(DIM);
}
- qh->NOerrexit= True;
+ qh NOerrexit= True;
}
+#if qh_QHpointer /* see user.h */
{
- qhT qh_qhB;
- qhT *qhB= &qh_qhB;
+ qhT *oldqhA, *oldqhB;
coordT pointsB[DIM*TOTpoints]; /* array of coordinates for each point */
- printf( "\nCompute a new triangulation as a separate instance of Qhull\n");
+ 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(qhB, pointsB, numpoints, dim, (int)time(NULL)+1);
+ makeDelaunay(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,
+ qh_printmatrix(outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(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);
- /* Exiting the block frees qh_qhB */
+ 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();
}
- qh_freeqhull(qh, !qh_ALL); /* free long memory */
- qh_memfreeshort(qh, &curlong, &totlong); /* free short memory and memory allocator */
+#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(qh, outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1);
+ 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]
+ 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,
+ exitcode= qh_new_qhull(dim+1, numpoints, points, ismalloc,
flags, outfile, errfile);
if (!exitcode)
- print_summary(qh);
- qh_freeqhull(qh, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
+ 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/user_eg/user_eg.pro b/src/user_eg/user_eg.pro
index e5fabba..9dda010 100644
--- a/src/user_eg/user_eg.pro
+++ b/src/user_eg/user_eg.pro
@@ -1,9 +1,11 @@
# -------------------------------------------------
-# user_eg.pro -- Qt project for Qhull demonstration
+# user_eg.pro -- Qt project for Qhull demonstration using shared Qhull library
+#
+# It uses reentrant Qhull
# -------------------------------------------------
-include(../qhull-app-c_r.pri)
+include(../qhull-app-shared_r.pri)
TARGET = user_eg
-SOURCES += user_eg.c
+SOURCES += user_eg_r.c
diff --git a/src/user_egp/user_eg_p.c b/src/user_eg/user_eg_r.c
similarity index 67%
rename from src/user_egp/user_eg_p.c
rename to src/user_eg/user_eg_r.c
index fecf304..6090539 100644
--- a/src/user_egp/user_eg_p.c
+++ b/src/user_eg/user_eg_r.c
@@ -1,327 +1,326 @@
-/*<html><pre> -<a href="../libqhull/qh-user.htm"
+/*<html><pre> -<a href="../libqhull_r/qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
- user_eg.c
- sample code for calling qhull() from an application
+ 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.c and user_eg2.c.
+ 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.cpp
+ 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 user_eg'
+ compiled by 'make bin/user_eg'
see libqhull.h for data structures, macros, and user-callable functions.
*/
#define qh_QHimport
-#include "qhull_a.h"
+#include "libqhull_r/qhull_ra.h"
/*-------------------------------------------------
-internal function prototypes
*/
-void print_summary(void);
+void print_summary(qhT *qh);
void makecube(coordT *points, int numpoints, int dim);
-void makeDelaunay(coordT *points, int numpoints, int dim, int seed);
-void findDelaunay(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()
+-print_summary(qh)
*/
-void print_summary(void) {
+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);
+ qh->num_vertices, qh->num_facets);
FORALLfacets {
- for (k=0; k < qh hull_dim; k++)
+ 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; j<numpoints; j++) {
point= points + j*dim;
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makecube.*/
/*--------------------------------------------------
-makeDelaunay- set points for dim Delaunay triangulation of random points
points is numpoints X dim.
notes:
makeDelaunay() in user_eg2.c uses qh_setdelaunay() to project points in place.
*/
-void makeDelaunay(coordT *points, int numpoints, int dim, int seed) {
+void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim, int seed) {
int j,k;
coordT *point, realr;
printf("seed: %d\n", seed);
- qh_RANDOMseed_( seed);
+ qh_RANDOMseed_(qh, seed);
for (j=0; j<numpoints; j++) {
point= points + j*dim;
for (k= 0; k < dim; k++) {
realr= qh_RANDOMint;
point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
}
}
} /*.makeDelaunay.*/
/*--------------------------------------------------
-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 <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
*/
-void findDelaunay(int dim) {
+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(dim+1, 1, point);
- facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
+ 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_ERRqhull, facet, NULL);
+ 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<numpoints; j++) {
point= points + j*(dim+1);
point[dim]= -1.0; /* offset */
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makehalf.*/
#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
#define SIZEcube (1<<DIM)
#define SIZEdiamond (2*DIM)
#define TOTpoints (SIZEcube + SIZEdiamond)
/*--------------------------------------------------
-main- derived from call_qhull in user.c
see program header
this contains three runs of Qhull for convex hull, Delaunay
triangulation or Voronoi vertices, and halfspace intersection
*/
int main(int argc, char *argv[]) {
int dim= DIM; /* dimension of points */
int numpoints; /* number of points */
coordT points[(DIM+1)*TOTpoints]; /* array of coordinates for each point */
coordT *rows[TOTpoints];
boolT ismalloc= False; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[250]; /* option flags for qhull, see qh-quick.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 */
int i;
- printf("This is the output from user_eg.c\n\n\
+ qhT qh_qh; /* Qhull's data structure. First argument of most calls */
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK
+
+ qh_zero(qh, errfile);
+
+ printf("This is the output from user_eg_r.c\n\n\
It shows how qhull() may be called from an application using the qhull\n\
-shared library. It is not part of qhull itself. If it appears accidently,\n\
-please remove user_eg.c from your project.\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
+reentrant library. user_eg is not part of qhull itself. If it appears\n\
+accidently, please remove user_eg_r.c from your project. If it fails\n\
+immediately, user_eg_r.c was incorrectly linked to the non-reentrant library.\n\
+Also try 'user_eg T1 2>&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(outfile, "input", rows, numpoints, dim);
- exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
+ 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->facet_list' contains the convex hull */
+ print_summary(qh);
FORALLfacets {
/* ... your code ... */
}
}
- qh_freeqhull(!qh_ALL); /* free long memory */
- qh_memfreeshort(&curlong, &totlong); /* free short memory and memory allocator */
+ 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
+ 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(points, numpoints, dim, (int)time(NULL));
+ makeDelaunay(qh, 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,
+ 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 */
+ /* '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();
+ print_summary(qh);
FORALLfacets {
/* ... your code ... */
}
printf( "\nfind %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim);
- exitcode= setjmp(qh errexit);
+ 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= False;
+ findDelaunay(qh, DIM);
}
- qh NOerrexit= True;
+ qh->NOerrexit= True;
}
-#if qh_QHpointer /* see user.h */
{
- qhT *oldqhA, *oldqhB;
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( "\nsave first triangulation and compute a new triangulation\n");
- oldqhA= qh_save_qhull();
+ 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(pointsB, numpoints, dim, (int)time(NULL)+1);
+ makeDelaunay(qhB, 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,
+ qh_printmatrix(qhB, outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(qhB, 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();
+ 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 */
}
-#endif
- qh_freeqhull(!qh_ALL); /* free long memory */
- qh_memfreeshort(&curlong, &totlong); /* free short memory and memory allocator */
+ 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(outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1);
+ 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]
+ 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,
+ exitcode= qh_new_qhull(qh, dim+1, numpoints, points, ismalloc,
flags, outfile, errfile);
if (!exitcode)
- print_summary();
- qh_freeqhull(!qh_ALL);
- qh_memfreeshort(&curlong, &totlong);
+ 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/user_eg2/user_eg2.c b/src/user_eg2/user_eg2.c
index eabe5b3..52fcfda 100644
--- a/src/user_eg2/user_eg2.c
+++ b/src/user_eg2/user_eg2.c
@@ -1,728 +1,738 @@
/*<html><pre> -<a href="../libqhull/qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
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.cpp for a C++ example
+ 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 user_eg2'
+ 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.
+ still write to 'qh ferr' (stderr) for error reporting and tracing.
Defining #if 1, also prevents user.o from being loaded.
*/
-#include "qhull_r.h"
+#include "qhull_a.h"
/*-------------------------------------------------
-internal function prototypes
*/
-void print_summary(qhT *qh);
+void print_summary(void);
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 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(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
+void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
/*-------------------------------------------------
--print_summary(qh)
+-print_summary()
*/
-void print_summary(qhT *qh) {
+void print_summary(void) {
facetT *facet;
int k;
printf("\n%d vertices and %d facets with normals:\n",
- qh->num_vertices, qh->num_facets);
+ qh num_vertices, qh num_facets);
FORALLfacets {
- for (k=0; k < qh->hull_dim; k++)
+ 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; j<numpoints; j++) {
point= points + j*dim;
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makecube.*/
/*--------------------------------------------------
-adddiamond- add diamond to convex hull
points is numpoints+numnew X dim.
notes:
qh_addpoint() does not make a copy of the point coordinates.
For inside points and some outside points, qh_findbestfacet performs
an exhaustive search for a visible facet. Algorithms that retain
previously constructed hulls should be faster for on-line construction
of the convex hull.
*/
-void adddiamond(qhT *qh, coordT *points, int numpoints, int numnew, int dim) {
+void adddiamond(coordT *points, int numpoints, int numnew, int dim) {
int j,k;
coordT *point;
facetT *facet;
boolT isoutside;
realT bestdist;
for (j= 0; j < numnew ; j++) {
point= points + (numpoints+j)*dim;
- if (points == qh->first_point) /* in case of 'QRn' */
- qh->num_points= numpoints+j+1;
+ if (points == qh first_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
+ 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);
+ facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
if (isoutside) {
- if (!qh_addpoint(qh, point, facet, False))
+ if (!qh_addpoint(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 num_vertices, qh num_facets);
/* qh_produce_output(); */
}
- if (qh->DOcheckmax)
- qh_check_maxout(qh);
- else if (qh->KEEPnearinside)
- qh_nearcoplanar(qh);
+ if (qh DOcheckmax)
+ qh_check_maxout();
+ else if (qh KEEPnearinside)
+ qh_nearcoplanar();
} /*.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) {
+void makeDelaunay(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);
+ qh_RANDOMseed_( seed);
for (j=0; j<numpoints; j++) {
point= points + j*dim;
for (k= 0; k < dim-1; k++) {
realr= qh_RANDOMint;
point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
}
}
- qh_setdelaunay(qh, dim, numpoints, points);
+ qh_setdelaunay(dim, numpoints, points);
} /*.makeDelaunay.*/
/*--------------------------------------------------
-addDelaunay- add points to dim-1 Delaunay triangulation
points is numpoints+numnew X dim. Each point is projected to a paraboloid.
notes:
qh_addpoint() does not make a copy of the point coordinates.
Since qh_addpoint() is not given a visible facet, it performs a directed
search of all facets. Algorithms that retain previously
constructed hulls may be faster.
*/
-void addDelaunay(qhT *qh, coordT *points, int numpoints, int numnew, int dim) {
+void addDelaunay(coordT *points, int numpoints, int numnew, int dim) {
int j,k;
coordT *point, realr;
facetT *facet;
realT bestdist;
boolT isoutside;
for (j= 0; j < numnew ; j++) {
point= points + (numpoints+j)*dim;
- if (points == qh->first_point) /* in case of 'QRn' */
- qh->num_points= numpoints+j+1;
+ if (points == qh first_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
+ 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);
+ qh_setdelaunay(dim, 1, point);
+ facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
if (isoutside) {
- if (!qh_addpoint(qh, point, facet, False))
+ if (!qh_addpoint(point, facet, False))
break; /* user requested an early exit with 'TVn' or 'TCn' */
}
- qh_printpoint(qh, stdout, "added point", point);
+ qh_printpoint(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 num_points, qh_setsize(qh other_points),
+ qh num_vertices, qh num_facets);
- /* qh_produce_output(qh); */
+ /* qh_produce_output(); */
}
- if (qh->DOcheckmax)
- qh_check_maxout(qh);
- else if (qh->KEEPnearinside)
- qh_nearcoplanar(qh);
+ if (qh DOcheckmax)
+ qh_check_maxout();
+ else if (qh KEEPnearinside)
+ qh_nearcoplanar();
} /*.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 <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
*/
-void findDelaunay(qhT *qh, int dim) {
+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(qh, dim, 1, point);
- facet= qh_findbestfacet(qh, point, qh_ALL, &bestdist, &isoutside);
+ 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, qh_ERRqhull, facet, NULL);
+ 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<numpoints; j++) {
point= points + j*(dim+1);
point[dim]= -1.0; /* offset */
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makehalf.*/
/*--------------------------------------------------
-addhalf- add halfspaces for a (dim)-d cube to the intersection
points is numpoints+numnew X dim+1
notes:
assumes dim < 100.
For makehalf(), points is the initial set of halfspaces with offsets.
It is transformed by qh_sethalfspace_all into a
(dim)-d set of newpoints. Qhull computed the convex hull of newpoints -
this is equivalent to the halfspace intersection of the
orginal halfspaces.
For addhalf(), the remainder of points stores the transforms of
the added halfspaces. Qhull computes the convex hull of newpoints
and the added points. qh_addpoint() does not make a copy of these points.
Since halfspace intersection is equivalent to a convex hull,
qh_findbestfacet may perform an exhaustive search
for a visible facet. Algorithms that retain previously constructed
intersections should be faster for on-line construction.
*/
-void addhalf(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
+void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
int j,k;
coordT *point, normal[100], offset, *next;
facetT *facet;
boolT isoutside;
realT bestdist;
for (j= 0; j < numnew ; j++) {
offset= -1.0;
for (k=dim; k--; ) {
if (j/2 == k) {
normal[k]= sqrt((coordT)dim); /* to normalize as in makehalf */
if (j & 1)
normal[k]= -normal[k];
}else
normal[k]= 0.0;
}
point= points + (numpoints+j)* (dim+1); /* does not use point[dim] */
- qh_sethalfspace(qh, dim, point, &next, normal, &offset, feasible);
- facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
+ qh_sethalfspace(dim, point, &next, normal, &offset, feasible);
+ facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
if (isoutside) {
- if (!qh_addpoint(qh, point, facet, False))
+ if (!qh_addpoint(point, facet, False))
break; /* user requested an early exit with 'TVn' or 'TCn' */
}
- qh_printpoint(qh, stdout, "added offset -1 and normal", normal);
+ qh_printpoint(stdout, "added offset -1 and normal", normal);
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); */
+ qh num_points, qh_setsize(qh other_points),
+ qh num_vertices, qh num_facets);
+ /* qh_produce_output(); */
}
- if (qh->DOcheckmax)
- qh_check_maxout(qh);
- else if (qh->KEEPnearinside)
- qh_nearcoplanar(qh);
+ if (qh DOcheckmax)
+ qh_check_maxout();
+ else if (qh KEEPnearinside)
+ qh_nearcoplanar();
} /*.addhalf.*/
#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
#define SIZEcube (1<<DIM)
#define SIZEdiamond (2*DIM)
#define TOTpoints (SIZEcube + SIZEdiamond)
/*--------------------------------------------------
-main- derived from call_qhull in user.c
see program header
this contains three runs of Qhull for convex hull, Delaunay
triangulation or Voronoi vertices, and halfspace intersection
*/
int main(int argc, char *argv[]) {
boolT ismalloc;
int curlong, totlong, exitcode;
char options [2000];
- qhT qh_qh;
- qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK
printf("This is the output from user_eg2.c\n\n\
It shows how qhull() may be called from an application in the same way as\n\
qconvex. It is not part of qhull itself. If it appears accidently,\n\
please remove user_eg2.c from your project.\n\n");
+#if qh_QHpointer /* see user.h */
+ if (qh_qh){
+ printf("QH6237: Qhull link error. The global variable qh_qh was not initialized\n\
+ to NULL by global.c. Please compile user_eg2.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
+
+
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);
+ qh_init_A(stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh errexit);
if (!exitcode) {
coordT array[TOTpoints][DIM];
- strcat(qh->rbox_command, "user_eg cube");
+ strcat(qh rbox_command, "user_eg cube");
sprintf(options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
- qh_initflags(qh, options);
+ qh_initflags(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);
+ 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(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);
+ 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, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
+ qh NOerrexit= True;
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
/*
Run 2: Delaunay triangulation
*/
- qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
- exitcode= setjmp(qh->errexit);
+ 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");
+ strcat(qh rbox_command, "user_eg Delaunay");
sprintf(options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
- qh_initflags(qh, options);
+ qh_initflags(options);
printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
- makeDelaunay(qh, array[0], SIZEcube, DIM);
+ 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 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);
+ 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(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_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(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);
+ 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(qh, DIM);
+ findDelaunay(DIM);
}
- qh->NOerrexit= True;
- qh_freeqhull(qh, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
+ qh NOerrexit= True;
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
/*
Run 3: halfspace intersection
*/
- qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
- exitcode= setjmp(qh->errexit);
+ 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");
+ strcat(qh rbox_command, "user_eg halfspaces");
sprintf(options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
- qh_initflags(qh, options);
+ qh_initflags(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
+ 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(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);
+ 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(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);
+ 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, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
+ qh NOerrexit= True;
+ qh NOerrexit= True;
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong) /* could also check previous runs */
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
totlong, curlong);
return exitcode;
} /* main */
#if 1 /* use 1 to prevent loading of io.o and user.o */
/*-------------------------------------------
-errexit- return exitcode to system after an error
assumes exitcode non-zero
prints useful information
see qh_errexit2() in libqhull.c for 2 facets
*/
-void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
+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");
+ 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);
+ 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");
+ 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");
+ 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);
+ 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) {
+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",
+ 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) {
+void qh_printfacetlist(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*/
+ qh_printbegin(qh ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
FORALLfacet_(facetlist) /*io.c*/
- qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall); /*io.c*/
+ qh_printafacet(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*/
+ 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);
+ 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) {
+void qh_printhelp_degenerate(FILE *fp) {
- if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
- qh_fprintf(qh, fp, 9368, "\n\
+ 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(qh, fp, 9369, "\n\
+ 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(qh, fp, 9370, "\
+ 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(qh, fp, 9371, "\
+ 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(qh, fp, 9372, "\
+ 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(qh, fp, 9373, "\
+ 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(qh, fp, 9374, "\
+ 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(qhT *qh, FILE *fp, realT minangle) {
+void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
- qh_fprintf(qh, fp, 9375, "qhull precision warning: \n\
+ 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(qhT *qh, FILE *fp) {
+void qh_printhelp_singular(FILE *fp) {
facetT *facet;
vertexT *vertex, **vertexp;
realT min, max, *coord, dist;
int i,k;
- qh_fprintf(qh, fp, 9376, "\n\
+ 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(qh, fp, "", qh->facet_list, NULL, qh_ALL);
+ qh hull_dim);
+ qh_printvertexlist(fp, "", qh facet_list, NULL, qh_ALL);
if (!qh_QUICKhelp)
- qh_fprintf(qh, fp, 9377, "\n\
+ 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(qh, fp, "center point", qh->hull_dim, qh->interior_point, -1);
- qh_fprintf(qh, fp, 9378, "\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(qh, fp, 9379, "facet");
+ qh_fprintf(fp, 9379, "facet");
FOREACHvertex_(facet->vertices)
- qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
+ qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
zinc_(Zdistio);
- qh_distplane(qh, qh->interior_point, facet, &dist);
- qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
+ qh_distplane(qh interior_point, facet, &dist);
+ qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
}
if (!qh_QUICKhelp) {
- if (qh->HALFspace)
- qh_fprintf(qh, fp, 9382, "\n\
+ 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(qh, fp, 9383,"\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(qh, fp, 9384, "\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(qh, fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
- for (k=0; k < qh->hull_dim; k++) {
+ 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) {
+ 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);
+ qh_fprintf(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\
+ 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);
+ qh DISTround);
#if REALfloat
- qh_fprintf(qh, fp, 9388, "\
+ qh_fprintf(fp, 9388, "\
- recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
#endif
- qh_fprintf(qh, fp, 9389, "\n\
+ 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(qh, fp, 9390, "\n\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(qhT *qh) {
+void qh_user_memsizes(void) {
- /* qh_memsize(qh, size); */
+ /* qh_memsize(size); */
} /* user_memsizes */
#endif
diff --git a/src/user_eg2/user_eg2.pro b/src/user_eg2/user_eg2.pro
index 71fb3e5..c841bfe 100644
--- a/src/user_eg2/user_eg2.pro
+++ b/src/user_eg2/user_eg2.pro
@@ -1,9 +1,11 @@
# -------------------------------------------------
-# user_eg2.pro -- Qt project for Qhull demonstration using shared Qhull dll
+# user_eg2.pro -- Qt project for Qhull demonstration using the static Qhull library
+#
+# It uses reentrant Qhull
# -------------------------------------------------
-include(../qhull-app-shared_r.pri)
+include(../qhull-app-c_r.pri)
TARGET = user_eg2
-SOURCES += user_eg2.c
+SOURCES += user_eg2_r.c
diff --git a/src/user_eg2p/user_eg2_p.c b/src/user_eg2/user_eg2_r.c
similarity index 63%
rename from src/user_eg2p/user_eg2_p.c
rename to src/user_eg2/user_eg2_r.c
index 3786bd6..9dfe8cc 100644
--- a/src/user_eg2p/user_eg2_p.c
+++ b/src/user_eg2/user_eg2_r.c
@@ -1,736 +1,736 @@
-/*<html><pre> -<a href="../libqhull/qh-user.htm"
+/*<html><pre> -<a href="../libqhull_r/qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
- user_eg2.c
+ user_eg2_r.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
+ 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.cpp for a C++ example
+ 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 user_eg2'
+ 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.
+ still write to 'qh->ferr' (stderr) for error reporting and tracing.
Defining #if 1, also prevents user.o from being loaded.
*/
-#include "qhull_a.h"
+#include "libqhull_r/qhull_ra.h"
/*-------------------------------------------------
-internal function prototypes
*/
-void print_summary(void);
+void print_summary(qhT *qh);
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 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(coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
+void addhalf(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
/*-------------------------------------------------
--print_summary()
+-print_summary(qh)
*/
-void print_summary(void) {
+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);
+ qh->num_vertices, qh->num_facets);
FORALLfacets {
- for (k=0; k < qh hull_dim; k++)
+ 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; j<numpoints; j++) {
point= points + j*dim;
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makecube.*/
/*--------------------------------------------------
-adddiamond- add diamond to convex hull
points is numpoints+numnew X dim.
notes:
qh_addpoint() does not make a copy of the point coordinates.
For inside points and some outside points, qh_findbestfacet performs
an exhaustive search for a visible facet. Algorithms that retain
previously constructed hulls should be faster for on-line construction
of the convex hull.
*/
-void adddiamond(coordT *points, int numpoints, int numnew, int dim) {
+void adddiamond(qhT *qh, coordT *points, int numpoints, int numnew, int dim) {
int j,k;
coordT *point;
facetT *facet;
boolT isoutside;
realT bestdist;
for (j= 0; j < numnew ; j++) {
point= points + (numpoints+j)*dim;
- if (points == qh first_point) /* in case of 'QRn' */
- qh num_points= numpoints+j+1;
+ if (points == qh->first_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
+ 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(point, !qh_ALL, &bestdist, &isoutside);
+ facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
if (isoutside) {
- if (!qh_addpoint(point, facet, False))
+ 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->num_vertices, qh->num_facets);
/* qh_produce_output(); */
}
- if (qh DOcheckmax)
- qh_check_maxout();
- else if (qh KEEPnearinside)
- qh_nearcoplanar();
+ 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(coordT *points, int numpoints, int dim) {
+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_( seed);
+ qh_RANDOMseed_(qh, seed);
for (j=0; j<numpoints; j++) {
point= points + j*dim;
for (k= 0; k < dim-1; k++) {
realr= qh_RANDOMint;
point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
}
}
- qh_setdelaunay(dim, numpoints, points);
+ qh_setdelaunay(qh, dim, numpoints, points);
} /*.makeDelaunay.*/
/*--------------------------------------------------
-addDelaunay- add points to dim-1 Delaunay triangulation
points is numpoints+numnew X dim. Each point is projected to a paraboloid.
notes:
qh_addpoint() does not make a copy of the point coordinates.
Since qh_addpoint() is not given a visible facet, it performs a directed
search of all facets. Algorithms that retain previously
constructed hulls may be faster.
*/
-void addDelaunay(coordT *points, int numpoints, int numnew, int dim) {
+void addDelaunay(qhT *qh, coordT *points, int numpoints, int numnew, int dim) {
int j,k;
coordT *point, realr;
facetT *facet;
realT bestdist;
boolT isoutside;
for (j= 0; j < numnew ; j++) {
point= points + (numpoints+j)*dim;
- if (points == qh first_point) /* in case of 'QRn' */
- qh num_points= numpoints+j+1;
+ if (points == qh->first_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
+ 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(dim, 1, point);
- facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
+ qh_setdelaunay(qh, dim, 1, point);
+ facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
if (isoutside) {
- if (!qh_addpoint(point, facet, False))
+ if (!qh_addpoint(qh, point, facet, False))
break; /* user requested an early exit with 'TVn' or 'TCn' */
}
- qh_printpoint(stdout, "added point", point);
+ 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 other_points),
- qh num_vertices, qh num_facets);
+ qh->num_points, qh_setsize(qh, qh->other_points),
+ qh->num_vertices, qh->num_facets);
- /* qh_produce_output(); */
+ /* qh_produce_output(qh); */
}
- if (qh DOcheckmax)
- qh_check_maxout();
- else if (qh KEEPnearinside)
- qh_nearcoplanar();
+ 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 <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
*/
-void findDelaunay(int dim) {
+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(dim, 1, point);
- facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
+ 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_ERRqhull, facet, NULL);
+ 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; j<numpoints; j++) {
point= points + j*(dim+1);
point[dim]= -1.0; /* offset */
for (k=dim; k--; ) {
if (j & ( 1 << k))
point[k]= 1.0;
else
point[k]= -1.0;
}
}
} /*.makehalf.*/
/*--------------------------------------------------
-addhalf- add halfspaces for a (dim)-d cube to the intersection
points is numpoints+numnew X dim+1
notes:
assumes dim < 100.
For makehalf(), points is the initial set of halfspaces with offsets.
It is transformed by qh_sethalfspace_all into a
(dim)-d set of newpoints. Qhull computed the convex hull of newpoints -
this is equivalent to the halfspace intersection of the
orginal halfspaces.
For addhalf(), the remainder of points stores the transforms of
the added halfspaces. Qhull computes the convex hull of newpoints
and the added points. qh_addpoint() does not make a copy of these points.
Since halfspace intersection is equivalent to a convex hull,
qh_findbestfacet may perform an exhaustive search
for a visible facet. Algorithms that retain previously constructed
intersections should be faster for on-line construction.
*/
-void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
+void addhalf(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
int j,k;
coordT *point, normal[100], offset, *next;
facetT *facet;
boolT isoutside;
realT bestdist;
for (j= 0; j < numnew ; j++) {
offset= -1.0;
for (k=dim; k--; ) {
if (j/2 == k) {
normal[k]= sqrt((coordT)dim); /* to normalize as in makehalf */
if (j & 1)
normal[k]= -normal[k];
}else
normal[k]= 0.0;
}
point= points + (numpoints+j)* (dim+1); /* does not use point[dim] */
- qh_sethalfspace(dim, point, &next, normal, &offset, feasible);
- facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
+ qh_sethalfspace(qh, dim, point, &next, normal, &offset, feasible);
+ facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
if (isoutside) {
- if (!qh_addpoint(point, facet, False))
+ if (!qh_addpoint(qh, point, facet, False))
break; /* user requested an early exit with 'TVn' or 'TCn' */
}
- qh_printpoint(stdout, "added offset -1 and normal", normal);
+ qh_printpoint(qh, stdout, "added offset -1 and normal", normal);
printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
- qh num_points, qh_setsize(qh other_points),
- qh num_vertices, qh num_facets);
- /* qh_produce_output(); */
+ 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();
- else if (qh KEEPnearinside)
- qh_nearcoplanar();
+ 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<<DIM)
#define SIZEdiamond (2*DIM)
#define TOTpoints (SIZEcube + SIZEdiamond)
/*--------------------------------------------------
-main- derived from call_qhull in user.c
see program header
this contains three runs of Qhull for convex hull, Delaunay
triangulation or Voronoi vertices, and halfspace intersection
*/
int main(int argc, char *argv[]) {
boolT ismalloc;
int curlong, totlong, exitcode;
char options [2000];
+ qhT qh_qh;
+ qhT *qh= &qh_qh; /* Alternatively -- qhT *qh= (qhT*)malloc(sizeof(qhT)) */
- printf("This is the output from user_eg2.c\n\n\
-It shows how qhull() may be called from an application in the same way as\n\
-qconvex. It is not part of qhull itself. If it appears accidently,\n\
-please remove user_eg2.c from your project.\n\n");
-
-#if qh_QHpointer /* see user.h */
- if (qh_qh){
- printf("QH6237: Qhull link error. The global variable qh_qh was not initialized\n\
- to NULL by global.c. Please compile user_eg2.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
+ QHULL_LIB_CHECK
+ printf("This is the output from user_eg2_r.c\n\n\
+It shows how qhull() may be called from an application using qhull's\n\
+static, reentrant library. user_eg2 is not part of qhull itself. If it\n\
+appears accidently, please remove user_eg2_r.c from your project. If it fails\n\
+immediately, user_eg2_r.c was incorrectly linked to the non-reentrant library.\n\
+Also try 'user_eg2 T1 2>&1'\n\n");
ismalloc= False; /* True if qh_freeqhull should 'free(array)' */
/*
Run 1: convex hull
*/
- qh_init_A(stdin, stdout, stderr, 0, NULL);
- exitcode= setjmp(qh errexit);
+ qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh->errexit);
if (!exitcode) {
coordT array[TOTpoints][DIM];
- strcat(qh rbox_command, "user_eg cube");
+ qh->NOerrexit= False;
+ strcat(qh->rbox_command, "user_eg cube");
sprintf(options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
- qh_initflags(options);
+ qh_initflags(qh, 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();
+ 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(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();
+ 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_ALL);
- qh_memfreeshort(&curlong, &totlong);
+ qh->NOerrexit= True;
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
/*
Run 2: Delaunay triangulation
*/
- qh_init_A(stdin, stdout, stderr, 0, NULL);
- exitcode= setjmp(qh errexit);
+ qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh->errexit);
if (!exitcode) {
coordT array[TOTpoints][DIM];
- strcat(qh rbox_command, "user_eg Delaunay");
+ qh->NOerrexit= False;
+ strcat(qh->rbox_command, "user_eg Delaunay");
sprintf(options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
- qh_initflags(options);
+ qh_initflags(qh, options);
printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
- makeDelaunay(array[0], SIZEcube, DIM);
+ 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->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();
+ 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();
- print_summary();
- qh_produce_output(); /* delete this line to help avoid io.c */
- if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
- qh_check_points();
+ 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(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();
+ 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(DIM);
+ findDelaunay(qh, DIM);
}
- qh NOerrexit= True;
- qh_freeqhull(!qh_ALL);
- qh_memfreeshort(&curlong, &totlong);
+ qh->NOerrexit= True;
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
/*
Run 3: halfspace intersection
*/
- qh_init_A(stdin, stdout, stderr, 0, NULL);
- exitcode= setjmp(qh errexit);
+ 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;
- strcat(qh rbox_command, "user_eg halfspaces");
+ qh->NOerrexit= False;
+ strcat(qh->rbox_command, "user_eg halfspaces");
sprintf(options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
- qh_initflags(options);
+ qh_initflags(qh, 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
+ 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( 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();
+ 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(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();
+ 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_ALL);
- qh_memfreeshort(&curlong, &totlong);
+ qh->NOerrexit= True;
+ qh->NOerrexit= True;
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong) /* could also check previous runs */
fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
totlong, curlong);
return exitcode;
} /* main */
#if 1 /* use 1 to prevent loading of io.o and user.o */
/*-------------------------------------------
-errexit- return exitcode to system after an error
assumes exitcode non-zero
prints useful information
see qh_errexit2() in libqhull.c for 2 facets
*/
-void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
+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");
+ 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);
+ 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");
+ 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");
+ 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);
+ 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) {
+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",
+ 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) {
+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 ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
+ qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
FORALLfacet_(facetlist) /*io.c*/
- qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall); /*io.c*/
+ qh_printafacet(qh, 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*/
+ 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);
+ 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) {
+void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
- if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2)
- qh_fprintf(fp, 9368, "\n\
+ 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(fp, 9369, "\n\
+ 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(fp, 9370, "\
+ 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(fp, 9371, "\
+ 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(fp, 9372, "\
+ 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(fp, 9373, "\
+ 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(fp, 9374, "\
+ 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(FILE *fp, realT minangle) {
+void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
- qh_fprintf(fp, 9375, "qhull precision warning: \n\
+ 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(FILE *fp) {
+void qh_printhelp_singular(qhT *qh, FILE *fp) {
facetT *facet;
vertexT *vertex, **vertexp;
realT min, max, *coord, dist;
int i,k;
- qh_fprintf(fp, 9376, "\n\
+ 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(fp, "", qh facet_list, NULL, qh_ALL);
+ qh->hull_dim);
+ qh_printvertexlist(qh, fp, "", qh->facet_list, NULL, qh_ALL);
if (!qh_QUICKhelp)
- qh_fprintf(fp, 9377, "\n\
+ 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(fp, "center point", qh hull_dim, qh interior_point, -1);
- qh_fprintf(fp, 9378, "\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(fp, 9379, "facet");
+ qh_fprintf(qh, fp, 9379, "facet");
FOREACHvertex_(facet->vertices)
- qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
+ qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
zinc_(Zdistio);
- qh_distplane(qh interior_point, facet, &dist);
- qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
+ 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(fp, 9382, "\n\
+ 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(fp, 9383,"\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(fp, 9384, "\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(fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
- for (k=0; k < qh hull_dim; k++) {
+ 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) {
+ 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);
+ qh_fprintf(qh, fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
}
if (!qh_QUICKhelp) {
- qh_fprintf(fp, 9387, "\n\
+ 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);
+ qh->DISTround);
#if REALfloat
- qh_fprintf(fp, 9388, "\
+ qh_fprintf(qh, fp, 9388, "\
- recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
#endif
- qh_fprintf(fp, 9389, "\n\
+ 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(fp, 9390, "\n\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(void) {
+void qh_user_memsizes(qhT *qh) {
- /* qh_memsize(size); */
+ QHULL_UNUSED(qh);
+ /* qh_memsize(qh, size); */
} /* user_memsizes */
#endif
diff --git a/src/user_eg2p/user_eg2p.pro b/src/user_eg2p/user_eg2p.pro
deleted file mode 100644
index 26af0cb..0000000
--- a/src/user_eg2p/user_eg2p.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-# -------------------------------------------------
-# user_eg2.pro -- Deprecated Qt project for Qhull demonstration using shared Qhull dll
-# -------------------------------------------------
-
-include(../qhull-app-shared.pri)
-
-TARGET = user_eg2p
-
-SOURCES += ../user_eg2p/user_eg2_p.c
diff --git a/src/user_eg3/user_eg3.pro b/src/user_eg3/user_eg3.pro
index cb17b17..35372fb 100644
--- a/src/user_eg3/user_eg3.pro
+++ b/src/user_eg3/user_eg3.pro
@@ -1,10 +1,12 @@
# -------------------------------------------------
# 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.cpp
+SOURCES += user_eg3_r.cpp
diff --git a/src/user_eg3/user_eg3.cpp b/src/user_eg3/user_eg3_r.cpp
similarity index 86%
rename from src/user_eg3/user_eg3.cpp
rename to src/user_eg3/user_eg3_r.cpp
index 5459484..5dd2b8b 100644
--- a/src/user_eg3/user_eg3.cpp
+++ b/src/user_eg3/user_eg3_r.cpp
@@ -1,157 +1,161 @@
-#//! user_eg3.cpp -- Invoke rbox and qhull from C++
+#//! user_eg3_r.cpp -- Invoke rbox and qhull from C++
-#include "RboxPoints.h"
-#include "QhullError.h"
-#include "QhullQh.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "QhullLinkedList.h"
-#include "QhullVertex.h"
-#include "Qhull.h"
+#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 <cstdio> /* for printf() of help message */
#include <ostream>
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)
{
- bool printFacets= false; // FIXUP not used
if(strcmp(argv[1], "eg-100")==0){
RboxPoints rbox("100");
Qhull q(rbox, "");
QhullFacetList facets= q.facetList();
cout << facets;
return 0;
}
- return 0;
-#if 0
+ bool printFacets= false;
RboxPoints rbox;
Qhull qhull;
int readingRbox= 0;
int readingQhull= 0;
for(int i=1; i<argc; i++){
if(strcmp(argv[i], "rbox")==0){
if(readingRbox!=0 || readingQhull!=0){
cerr << "user_eg3 -- \"rbox\" must be first" << endl;
return 1;
}
readingRbox++;
}else if(strcmp(argv[i], "qhull")==0
|| strcmp(argv[i], "qhull-cout")==0){
if(readingQhull){
cerr << "user_eg3 -- only one \"qhull\" or \"qhull-cout\" allowed." << endl;
return 1;
}
if(strcmp(argv[i], "qhull-cout")==0){
qhull.setOutputStream(&cout);
}
if(rbox.isEmpty()){
if(readingRbox){
rbox.appendPoints("10 D2");
}else{
cerr << "Enter dimension count coordinates. End with ^Z (Windows) or ^D (Unix).\n";
rbox.appendPoints(cin);
}
}
readingQhull++;
readingRbox= 0;
}else if(strcmp(argv[i], "facets")==0){
printFacets= true;
}else if(readingRbox){
readingRbox++;
cerr << "rbox " << argv[i] << endl;
rbox.appendPoints(argv[i]);
if(rbox.hasRboxMessage()){
cerr << "user_eg3 " << argv[i] << " -- " << rbox.rboxMessage();
return rbox.rboxStatus();
}
}else if(readingQhull){
if(readingQhull==1){
qhull.runQhull(rbox, argv[i]);
qhull.outputQhull();
}else{
qhull.outputQhull(argv[i]);
}
readingQhull++;
if(qhull.hasQhullMessage()){
cerr << "\nResults of " << argv[i] << "\n" << qhull.qhullMessage();
qhull.clearQhullMessage();
}
}else{
cerr << "user_eg3 error: Expecting qhull, qhull-cout, or rbox. Got " << argv[i] << endl;
return 1;
}
}//foreach argv
if(readingRbox){
cout << rbox;
return 0;
}
if(readingQhull==1){ // e.g., rbox 10 qhull
qhull.runQhull(rbox, "");
qhull.outputQhull();
if(qhull.hasQhullMessage()){
cerr << "\nResults of qhull\n" << qhull.qhullMessage();
qhull.clearQhullMessage();
}
}
- if(qhull.useOutputStream){
+ if(qhull.hasOutputStream()){
return 0;
}
if(printFacets){
QhullFacetList facets= qhull.facetList();
cout << "\nFacets created by Qhull::runQhull()\n" << facets;
}
return 0;
-#endif
}//user_eg3
diff --git a/src/user_eg3p/user_eg3_p.cpp b/src/user_eg3p/user_eg3_p.cpp
deleted file mode 100644
index a94b552..0000000
--- a/src/user_eg3p/user_eg3_p.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#//! user_eg3.cpp -- Invoke rbox and qhull from C++
-
-#include "RboxPoints.h"
-#include "QhullError.h"
-#include "QhullQh.h"
-#include "QhullFacet.h"
-#include "QhullFacetList.h"
-#include "QhullLinkedList.h"
-#include "QhullVertex.h"
-#include "Qhull.h"
-
-#include <cstdio> /* for printf() of help message */
-#include <ostream>
-
-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\
- 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\
- 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) {
-
- 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)
-{
- bool printFacets= false;
- if(strcmp(argv[1], "eg-100")==0){
- RboxPoints rbox;
- rbox.appendPoints("100");
- Qhull qhull;
- qhull.runQhull(rbox, "");
- QhullFacetList facets= qhull.facetList();
- cout << facets;
- return 0;
- }
- RboxPoints rbox;
- Qhull qhull;
- int readingRbox= 0;
- int readingQhull= 0;
- for(int i=1; i<argc; i++){
- if(strcmp(argv[i], "rbox")==0){
- if(readingRbox!=0 || readingQhull!=0){
- cerr << "user_eg3 -- \"rbox\" must be first" << endl;
- return 1;
- }
- readingRbox++;
- }else if(strcmp(argv[i], "qhull")==0
- || strcmp(argv[i], "qhull-cout")==0){
- if(readingQhull){
- cerr << "user_eg3 -- only one \"qhull\" or \"qhull-cout\" allowed." << endl;
- return 1;
- }
- if(strcmp(argv[i], "qhull-cout")==0){
- qhull.setOutputStream(&cout);
- }
- if(rbox.isEmpty()){
- if(readingRbox){
- rbox.appendPoints("10 D2");
- }else{
- cerr << "Enter dimension count coordinates. End with ^Z (Windows) or ^D (Unix).\n";
- rbox.appendPoints(cin);
- }
- }
- readingQhull++;
- readingRbox= 0;
- }else if(strcmp(argv[i], "facets")==0){
- printFacets= true;
- }else if(readingRbox){
- readingRbox++;
- cerr << "rbox " << argv[i] << endl;
- rbox.appendPoints(argv[i]);
- if(rbox.hasRboxMessage()){
- cerr << "user_eg3 " << argv[i] << " -- " << rbox.rboxMessage();
- return rbox.rboxStatus();
- }
- }else if(readingQhull){
- if(readingQhull==1){
- qhull.runQhull(rbox, argv[i]);
- qhull.outputQhull();
- }else{
- qhull.outputQhull(argv[i]);
- }
- readingQhull++;
- if(qhull.hasQhullMessage()){
- cerr << "\nResults of " << argv[i] << "\n" << qhull.qhullMessage();
- qhull.clearQhullMessage();
- }
- }else{
- cerr << "user_eg3 error: Expecting qhull, qhull-cout, or rbox. Got " << argv[i] << endl;
- return 1;
- }
- }//foreach argv
- if(readingRbox){
- cout << rbox;
- return 0;
- }
- if(readingQhull==1){ // e.g., rbox 10 qhull
- qhull.runQhull(rbox, "");
- qhull.outputQhull();
- if(qhull.hasQhullMessage()){
- cerr << "\nResults of qhull\n" << qhull.qhullMessage();
- qhull.clearQhullMessage();
- }
- }
- if(qhull.useOutputStream){
- return 0;
- }
- if(printFacets){
- QhullFacetList facets= qhull.facetList();
- cout << "\nFacets created by Qhull::runQhull()\n" << facets;
- }
- return 0;
-}//user_eg3
-
diff --git a/src/user_eg3p/user_eg3p.pro b/src/user_eg3p/user_eg3p.pro
deleted file mode 100644
index f60a62f..0000000
--- a/src/user_eg3p/user_eg3p.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-# -------------------------------------------------
-# user_eg3.pro -- Deprecated Qt project for cpp demonstration use pointer version of qhull
-# -------------------------------------------------
-
-include(../qhull-app-cpp_p.pri)
-
-TARGET = user_eg3p
-CONFIG -= qt
-
-SOURCES += ../user_eg3p/user_eg3_p.cpp
diff --git a/src/user_egp/user_egp.pro b/src/user_egp/user_egp.pro
deleted file mode 100644
index 03d10b9..0000000
--- a/src/user_egp/user_egp.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-# -------------------------------------------------
-# user_egp.pro -- Deprecated Qt project for Qhull demonstration
-# -------------------------------------------------
-
-include(../qhull-app-sharedp.pri)
-
-TARGET = user_egp
-
-SOURCES += ../user_egp/user_eg_p.c

Event Timeline