From e17d98e034b487d456a9e6aeb56558146cdec328 Mon Sep 17 00:00:00 2001 From: bbarber <bradb@shore.net> Date: Sat, 5 Dec 2009 09:51:43 -0500 Subject: [PATCH] First cut at a C++ interface to Qhull. Includes QTest files for each class and user-eg3.c for demonstrating the interface. See src/Changes.txt for change notes and to do. See FIXUP for problems See WARN64 for 64-bit problems --- Announce.txt | 8 +- COPYING.txt | 2 +- ConvexHull | 1 + README.txt | 26 +- REGISTER.txt | 4 +- cpp/Coordinates.cpp | 183 ++ cpp/Coordinates.h | 125 ++ cpp/PointCoordinates.cpp | 292 +++ cpp/PointCoordinates.h | 120 ++ cpp/Qhull.cpp | 476 +++++ cpp/Qhull.h | 136 ++ cpp/QhullError.cpp | 30 + cpp/QhullError.h | 69 + cpp/QhullEvent.cpp | 18 + cpp/QhullEvent.h | 71 + cpp/QhullFacet.cpp | 512 +++++ cpp/QhullFacet.h | 151 ++ cpp/QhullFacetList.cpp | 123 ++ cpp/QhullFacetList.h | 105 + cpp/QhullFacetSet.cpp | 125 ++ cpp/QhullFacetSet.h | 94 + cpp/QhullHyperplane.cpp | 147 ++ cpp/QhullHyperplane.h | 123 ++ cpp/QhullIterator.h | 171 ++ cpp/QhullLinkedList.h | 369 ++++ cpp/QhullLog.cpp | 155 ++ cpp/QhullLog.h | 96 + cpp/QhullPoint.cpp | 158 ++ cpp/QhullPoint.h | 138 ++ cpp/QhullPointSet.cpp | 200 ++ cpp/QhullPointSet.h | 254 +++ cpp/QhullPoints.cpp | 219 ++ cpp/QhullPoints.h | 241 +++ cpp/QhullQh.cpp | 151 ++ cpp/QhullQh.h | 57 + cpp/QhullRidge.cpp | 84 + cpp/QhullRidge.h | 108 + cpp/QhullSet.cpp | 47 + cpp/QhullSet.h | 346 ++++ cpp/QhullSets.h | 27 + cpp/QhullStat.cpp | 42 + cpp/QhullStat.h | 52 + cpp/QhullVertex.cpp | 87 + cpp/QhullVertex.h | 100 + cpp/QhullVertexSet.cpp | 110 + cpp/QhullVertexSet.h | 79 + cpp/RboxPoints.cpp | 219 ++ cpp/RboxPoints.h | 67 + cpp/UsingQhullLib.cpp | 372 ++++ cpp/UsingQhullLib.h | 139 ++ cpp/functionObjects.h | 63 + {src => cpp}/qhull_interface.cpp | 10 +- cpp/qhulltest/Coordinates_test.cpp | 547 +++++ cpp/qhulltest/PointCoordinates_test.cpp | 343 ++++ cpp/qhulltest/Point_test.cpp | 238 +++ cpp/qhulltest/QhullFacetList_test.cpp | 232 +++ cpp/qhulltest/QhullFacetSet_test.cpp | 185 ++ cpp/qhulltest/QhullFacet_test.cpp | 260 +++ cpp/qhulltest/QhullHyperplane_test.cpp | 442 ++++ cpp/qhulltest/QhullLinkedList_test.cpp | 330 +++ cpp/qhulltest/QhullPointSet_test.cpp | 398 ++++ cpp/qhulltest/QhullPoint_test.cpp | 423 ++++ cpp/qhulltest/QhullPoints_test.cpp | 508 +++++ cpp/qhulltest/QhullRidge_test.cpp | 162 ++ cpp/qhulltest/QhullSet_test.cpp | 400 ++++ cpp/qhulltest/QhullVertexSet_test.cpp | 185 ++ cpp/qhulltest/QhullVertex_test.cpp | 159 ++ cpp/qhulltest/Qhull_test.cpp | 345 ++++ cpp/qhulltest/RboxPoints_test.cpp | 215 ++ cpp/qhulltest/UsingQhullLib_test.cpp | 210 ++ cpp/qhulltest/qhulltest.cpp | 79 + cpp/road/RoadError.cpp | 158 ++ cpp/road/RoadError.h | 86 + cpp/road/RoadLogEvent.cpp | 117 ++ cpp/road/RoadLogEvent.h | 77 + cpp/road/RoadTest.cpp | 84 + cpp/road/RoadTest.h | 100 + cpp/user_eg3.cpp | 134 ++ html/index.htm | 112 +- html/normal_voronoi_knauss_oesterle.jpg | Bin 0 -> 23924 bytes html/qconvex.htm | 2 +- html/qdelau_f.htm | 2 +- html/qdelaun.htm | 102 +- html/{qh-in.htm => qh-code.htm} | 342 ++- html/qh-eg.htm | 2 +- html/qh-faq.htm | 394 ++-- html/qh-get.htm | 77 +- html/qh-impre.htm | 97 +- html/qh-optc.htm | 2 +- html/qh-optf.htm | 209 +- html/qh-optg.htm | 2 +- html/qh-opto.htm | 12 +- html/qh-optp.htm | 2 +- html/qh-optq.htm | 2 +- html/qh-optt.htm | 2 +- html/qh-quick.htm | 80 +- html/qhalf.htm | 7 +- html/qhull-cpp.xml | 213 ++ html/qhull.htm | 2 +- html/qhull.man | 14 +- html/qhull.txt | 24 +- html/qvoron_f.htm | 2 +- html/qvoronoi.htm | 102 +- index.htm | 117 +- qtpro/qhull-qt/qhull-qt.pro | 84 + qtpro/qhulllib/qhulllib.pro | 59 + src/Changes.txt | 241 ++- src/Make-config.sh | 15 +- src/{Makefile => Makefile.txt} | 23 +- src/Mborland | 15 +- src/geom.c | 381 ++-- src/geom.h | 99 +- src/geom2.c | 899 ++++---- src/global.c | 1296 ++++++------ src/index.htm | 30 +- src/io.c | 2513 +++++++++++------------ src/io.h | 81 +- src/mem.c | 266 ++- src/mem.h | 103 +- src/merge.c | 882 ++++---- src/merge.h | 74 +- src/poly.c | 250 +-- src/poly.h | 118 +- src/poly2.c | 917 +++++---- src/qconvex.c | 38 +- src/qdelaun.c | 40 +- src/qh-geom.htm | 20 +- src/qh-globa.htm | 28 +- src/qh-io.htm | 14 +- src/qh-mem.htm | 7 +- src/qh-merge.htm | 10 +- src/qh-poly.htm | 50 +- src/qh-qhull.htm | 72 +- src/qh-set.htm | 8 +- src/qh-stat.htm | 6 +- src/qh-user.htm | 31 +- src/qhalf.c | 38 +- src/qhull.h | 1022 +-------- src/qhull_a.h | 119 +- src/{qhull.c => qhulllib.c} | 476 ++--- src/qhulllib.h | 1094 ++++++++++ src/qset.c | 195 +- src/qset.h | 42 +- src/qvoronoi.c | 38 +- src/random.c | 243 +++ src/random.h | 34 + src/rbox.c | 759 +------ src/rboxlib.c | 788 +++++++ src/stat.c | 206 +- src/stat.h | 44 +- src/unix.c | 54 +- src/user.c | 289 ++- src/user.h | 268 ++- src/user_eg.c | 38 +- src/user_eg2.c | 66 +- src/usermem.c | 64 + src/userprintf.c | 64 + vcproj/qhull.sln | 134 ++ vcproj/qhull.vcproj | 227 ++ vcproj/qhullcpp.vcproj | 422 ++++ vcproj/qhulllib.vcproj | 635 ++++++ vcproj/qhulltest.vcproj | 699 +++++++ vcproj/rbox.vcproj | 236 +++ vcproj/user_eg3.vcproj | 217 ++ 164 files changed, 25283 insertions(+), 7339 deletions(-) create mode 160000 ConvexHull create mode 100644 cpp/Coordinates.cpp create mode 100644 cpp/Coordinates.h create mode 100644 cpp/PointCoordinates.cpp create mode 100644 cpp/PointCoordinates.h create mode 100644 cpp/Qhull.cpp create mode 100644 cpp/Qhull.h create mode 100644 cpp/QhullError.cpp create mode 100644 cpp/QhullError.h create mode 100644 cpp/QhullEvent.cpp create mode 100644 cpp/QhullEvent.h create mode 100644 cpp/QhullFacet.cpp create mode 100644 cpp/QhullFacet.h create mode 100644 cpp/QhullFacetList.cpp create mode 100644 cpp/QhullFacetList.h create mode 100644 cpp/QhullFacetSet.cpp create mode 100644 cpp/QhullFacetSet.h create mode 100644 cpp/QhullHyperplane.cpp create mode 100644 cpp/QhullHyperplane.h create mode 100644 cpp/QhullIterator.h create mode 100644 cpp/QhullLinkedList.h create mode 100644 cpp/QhullLog.cpp create mode 100644 cpp/QhullLog.h create mode 100644 cpp/QhullPoint.cpp create mode 100644 cpp/QhullPoint.h create mode 100644 cpp/QhullPointSet.cpp create mode 100644 cpp/QhullPointSet.h create mode 100644 cpp/QhullPoints.cpp create mode 100644 cpp/QhullPoints.h create mode 100644 cpp/QhullQh.cpp create mode 100644 cpp/QhullQh.h create mode 100644 cpp/QhullRidge.cpp create mode 100644 cpp/QhullRidge.h create mode 100644 cpp/QhullSet.cpp create mode 100644 cpp/QhullSet.h create mode 100644 cpp/QhullSets.h create mode 100644 cpp/QhullStat.cpp create mode 100644 cpp/QhullStat.h create mode 100644 cpp/QhullVertex.cpp create mode 100644 cpp/QhullVertex.h create mode 100644 cpp/QhullVertexSet.cpp create mode 100644 cpp/QhullVertexSet.h create mode 100644 cpp/RboxPoints.cpp create mode 100644 cpp/RboxPoints.h create mode 100644 cpp/UsingQhullLib.cpp create mode 100644 cpp/UsingQhullLib.h create mode 100644 cpp/functionObjects.h rename {src => cpp}/qhull_interface.cpp (92%) create mode 100644 cpp/qhulltest/Coordinates_test.cpp create mode 100644 cpp/qhulltest/PointCoordinates_test.cpp create mode 100644 cpp/qhulltest/Point_test.cpp create mode 100644 cpp/qhulltest/QhullFacetList_test.cpp create mode 100644 cpp/qhulltest/QhullFacetSet_test.cpp create mode 100644 cpp/qhulltest/QhullFacet_test.cpp create mode 100644 cpp/qhulltest/QhullHyperplane_test.cpp create mode 100644 cpp/qhulltest/QhullLinkedList_test.cpp create mode 100644 cpp/qhulltest/QhullPointSet_test.cpp create mode 100644 cpp/qhulltest/QhullPoint_test.cpp create mode 100644 cpp/qhulltest/QhullPoints_test.cpp create mode 100644 cpp/qhulltest/QhullRidge_test.cpp create mode 100644 cpp/qhulltest/QhullSet_test.cpp create mode 100644 cpp/qhulltest/QhullVertexSet_test.cpp create mode 100644 cpp/qhulltest/QhullVertex_test.cpp create mode 100644 cpp/qhulltest/Qhull_test.cpp create mode 100644 cpp/qhulltest/RboxPoints_test.cpp create mode 100644 cpp/qhulltest/UsingQhullLib_test.cpp create mode 100644 cpp/qhulltest/qhulltest.cpp create mode 100644 cpp/road/RoadError.cpp create mode 100644 cpp/road/RoadError.h create mode 100644 cpp/road/RoadLogEvent.cpp create mode 100644 cpp/road/RoadLogEvent.h create mode 100644 cpp/road/RoadTest.cpp create mode 100644 cpp/road/RoadTest.h create mode 100644 cpp/user_eg3.cpp create mode 100644 html/normal_voronoi_knauss_oesterle.jpg rename html/{qh-in.htm => qh-code.htm} (65%) create mode 100644 html/qhull-cpp.xml create mode 100644 qtpro/qhull-qt/qhull-qt.pro create mode 100644 qtpro/qhulllib/qhulllib.pro rename src/{Makefile => Makefile.txt} (88%) rename src/{qhull.c => qhulllib.c} (70%) create mode 100644 src/qhulllib.h create mode 100644 src/random.c create mode 100644 src/random.h create mode 100644 src/rboxlib.c create mode 100644 src/usermem.c create mode 100644 src/userprintf.c create mode 100644 vcproj/qhull.sln create mode 100644 vcproj/qhull.vcproj create mode 100644 vcproj/qhullcpp.vcproj create mode 100644 vcproj/qhulllib.vcproj create mode 100644 vcproj/qhulltest.vcproj create mode 100644 vcproj/rbox.vcproj create mode 100644 vcproj/user_eg3.vcproj diff --git a/Announce.txt b/Announce.txt index 5813e25..7433d4a 100644 --- a/Announce.txt +++ b/Announce.txt @@ -2,7 +2,7 @@ Qhull 2003.1 2003/12/30 http://www.qhull.org - http://savannah.gnu.org/projects/qhull/ + http://savannah.nongnu.org/projects/qhull/ http://www6.uniovi.es/ftp/pub/mirrors/geom.umn.edu/software/ghindex.html http://www.geomview.org http://www.geom.uiuc.edu @@ -24,9 +24,9 @@ To download Qhull: 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, Dec. 1996. + 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://citeseer.nj.nec.com/83502.html diff --git a/COPYING.txt b/COPYING.txt index 7230a27..aca3f52 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -1,4 +1,4 @@ - Qhull, Copyright (c) 1993-2003 + Qhull, Copyright (c) 1993-2008 The National Science and Technology Research Center for Computation and Visualization of Geometric Structures diff --git a/ConvexHull b/ConvexHull new file mode 160000 index 0000000..2ed029a --- /dev/null +++ b/ConvexHull @@ -0,0 +1 @@ +Subproject commit 2ed029ad94b4c0018c3e26fab9d78a2d139075f4 diff --git a/README.txt b/README.txt index 4cbbdde..a7aba9b 100644 --- a/README.txt +++ b/README.txt @@ -9,7 +9,7 @@ Convex hull, Delaunay triangulation, Voronoi diagrams, Halfspace intersection Available from: <http://www.qhull.org> - <http://savannah.gnu.org/projects/qhull> + <http://savannah.nongnu.org/projects/qhull> Version 1 (simplicial only): <http://www.qhull.org/download/qhull-1.0.tar.gz> @@ -44,9 +44,15 @@ Environment requirements 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 Savannah at http://savannah.gnu.org/projects/qhull/ + Qhull is on Savannah at http://savannah.nongnu.org/projects/qhull/ Qhull on Windows 95, 98, ME, NT, 2000, XP @@ -147,7 +153,7 @@ Compiling on Windows 95, 98, NT, 2000, XP Visual C++ quickstart for qhull.exe only: - create a "Win32 console application" called "qhull" - add the following files: - geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhull.c + geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhulllib.c qset.c stat.c unix.c user.c - create a "Win32 console application" called "rbox" - add rbox.c @@ -167,7 +173,7 @@ Compiling on Windows 95, 98, NT, 2000, XP - create a "Win32 static library" called "library" - move these files from "qhull source" - geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhull.c + geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhulllib.c qset.c stat.c user.c - set the library file (use the same for debug and release) - build the project @@ -265,8 +271,8 @@ src/ qvoronoi.htm qvoron_f.htm qh-eg.htm + qh-code.htm qh-impre.htm - qh-in.htm index.htm qh-opt*.htm qh-quick.htm @@ -281,9 +287,9 @@ src/ src/index.htm // index to source files qh-...htm // specific files user.h // header file of user definable constants - qhull.h // header file for qhull + qhulllib.h // header file for qhull unix.c // Unix front end to qhull - qhull.c // Quickhull algorithm with partitioning + qhulllib.c // Quickhull algorithm with partitioning user.c // user re-definable functions user_eg.c // example of incorporating qhull into a user program user_eg2.c // more complex example @@ -312,11 +318,11 @@ src/ Authors: C. Bradford Barber Hannu Huhdanpaa - bradb@qhull.org hannu@qhull.org + bradb@qhull.org hannu@qhull.org The Geometry Center University of Minnesota - Qhull 1.0 was developed under NSF grants NSF/DMS-8920161 and - NSF-CCR-91-15793 750-7504 at the Geometry Center and Harvard + 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/REGISTER.txt b/REGISTER.txt index 4682e02..ee19654 100644 --- a/REGISTER.txt +++ b/REGISTER.txt @@ -24,11 +24,11 @@ We need to know: We encourage you to cite the use of any Geometry Center software you have used in your publications. -To cite Qhull, use +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, - Dec 1996. http://www.qhull.org + 22(4):469-483, Dec 1996, http://www.qhull.org. Please send e-mail to diff --git a/cpp/Coordinates.cpp b/cpp/Coordinates.cpp new file mode 100644 index 0000000..04ac6d0 --- /dev/null +++ b/cpp/Coordinates.cpp @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/Coordinates.cpp#13 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#include <algorithm> +#include <iostream> + +#include "Coordinates.h" +#include "functionObjects.h" +#include "QhullError.h" + +#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 index, int length) const +{ + int newLength= length; + if(length<0 || index+length > count()){ + newLength= count()-index; + } + Coordinates result; + if(newLength>0){ + copy(begin()+index, begin()+(index+newLength), back_inserter(result)); + } + return result; +}//mid + +coordT Coordinates:: +value(int index, const coordT &defaultValue) const +{ + return ((index < 0 || index >= count()) ? defaultValue : (*this)[index]); +}//value + +#//Operator + +Coordinates Coordinates:: +operator+(const Coordinates &other) const +{ + Coordinates result(*this); + copy(other.begin(), other.end(), back_inserter(result)); + return result; +}//operator+ + +Coordinates & Coordinates:: +operator+=(const Coordinates &other) +{ + if(&other==this){ + Coordinates clone(other); + copy(clone.begin(), clone.end(), back_inserter(*this)); + }else{ + copy(other.begin(), other.end(), back_inserter(*this)); + } + return *this; +}//operator+= + +#//Read-write + +coordT Coordinates:: +takeAt(int index) +{ + coordT c= at(index); + erase(begin()+index); + return c; +}//takeAt + +coordT Coordinates:: +takeLast() +{ + coordT c= last(); + removeLast(); + return c; +}//takeLast + +void Coordinates:: +swap(int index, int other) +{ + coordT c= at(index); + at(index)= 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/cpp/Coordinates.h b/cpp/Coordinates.h new file mode 100644 index 0000000..272bb39 --- /dev/null +++ b/cpp/Coordinates.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/Coordinates.h#23 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHCOORDINATES_H +#define QHCOORDINATES_H + +#include "QhullError.h" +#include "QhullIterator.h" + +#include <ostream> +#include <vector> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! an allocated vector of point coordinates + //! Used by PointCoordinates for RboxPoints + //! A QhullPoint refers to previously allocated coordinates + class Coordinates; + + +class Coordinates : public std::vector<coordT> { + +#//Types + // inherited types -- const_iterator, const_pointer, const_reference, iterator, iterator_category, pointer, reference, size_type, value_type +public: + typedef Coordinates::iterator Iterator; + typedef Coordinates::const_iterator ConstIterator; + +#//Construct + Coordinates() {}; + explicit Coordinates(const std::vector<coordT> &other) : std::vector<coordT>(other) {} + Coordinates(const Coordinates &other) : std::vector<coordT>(other) {} + Coordinates &operator=(const Coordinates &other) { std::vector<coordT>::operator=(other); return *this; } + Coordinates &operator=(const std::vector<coordT> &other) { std::vector<coordT>::operator=(other); return *this; } + ~Coordinates() {} + +#//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 static_cast< std::vector<coordT> >(*this); } +#endif //QHULL_NO_STL +#ifdef QHULL_USES_QT + QList<coordT> toQList() const; +#endif //QHULL_USES_QT + +#//GetSet + // std::vector -- empty, size + int count() const { return static_cast<int>(size()); } + bool isEmpty() const { return empty(); } + +#//Element access + // std::vector -- at (const& only), back, front, [] + coordT &first() { return front(); } + const coordT &first() const { return front(); } + coordT &last() { return back(); } + const coordT &last() const { return back(); } + Coordinates mid(int index, int length= -1) const; + coordT value(int index, const coordT &defaultValue) const; + +#//Operator + // std::vector -- ==, != + Coordinates operator+(const Coordinates &other) const; + 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; } + +#//Iterator + // std::vector -- begin, end, *, [], ->, ++, --, +, -, ==, !=, <, <=, >, >= + inline const_iterator constBegin() const { return begin(); } + inline const_iterator constEnd() const { return end(); } + +#//Read-write + // std::vector -- clear, erase, insert, pop_back, push_back + void append(const coordT &c) { push_back(c); } + void insert(int before, const coordT &c) { insert(begin()+before, c); } + using std::vector<coordT>::insert; + void move(int from, int to) { insert(to, takeAt(from)); } + void pop_front() { removeFirst(); } + void prepend(const coordT &c) { insert(begin(), c); } + void push_front(const coordT &c) { insert(begin(), c); } + //removeAll below + void removeAt(int index) { erase(begin()+index); } + void removeFirst() { erase(begin()); } + void removeLast() { erase(--end()); } + void replace(int index, const coordT &c) { (*this)[index]= c; } + void swap(int index, int other); + coordT takeAt(int index); + coordT takeFirst() { return takeAt(0); } + coordT takeLast(); + +#//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); + +};//Coordinates + +//class CoordinatesIterator +QHULL_DECLARE_SEQUENTIAL_ITERATOR(Coordinates, coordT) +//class MutableCoordinatesIterator +QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Coordinates, coordT) + +}//namespace orgQhull + +#//Global functions + +std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c); + +#endif // QHCOORDINATES_H diff --git a/cpp/PointCoordinates.cpp b/cpp/PointCoordinates.cpp new file mode 100644 index 0000000..b292126 --- /dev/null +++ b/cpp/PointCoordinates.cpp @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/PointCoordinates.cpp#14 $$Change: 1095 $ +** $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> + +#include "QhullPoint.h" +#include "PointCoordinates.h" +#include "QhullError.h" + +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() +{ } + +#//Construct +PointCoordinates:: +PointCoordinates(int dimension) +: QhullPoints(dimension) +, point_coordinates() +, point_comment() +{ } + +PointCoordinates:: +PointCoordinates(const std::string &comment) +: QhullPoints() +, point_coordinates() +, point_comment() +{ + appendComment(comment); +} + +PointCoordinates:: +PointCoordinates(int dimension, const std::string &comment) +: QhullPoints(dimension) +, point_coordinates() +, point_comment() +{ + appendComment(comment); +} + +PointCoordinates:: +PointCoordinates(int dimension, const std::string &comment, int coordinateCount, const coordT *c) +: QhullPoints(dimension) +, point_coordinates() +, point_comment(comment) +{ + append(coordinateCount, 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) +{ + point_coordinates= other.point_coordinates; + point_comment= other.point_comment; + makeValid(); + return *this; +}//operator= + +PointCoordinates:: +~PointCoordinates() +{ } + +#//GetSet + +void PointCoordinates:: +checkValid() const +{ + if(getCoordinates().data()!=QhullPoints::point_first + || 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, point_first); + } +}//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 count, const coordT *c) +{ + if(count<=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(count); + for(int i=count; i--; ){ // FIXUP copy(c, c+count, point_coordinates.end()); + point_coordinates.push_back(*c++); + } + 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 coordinateCount= 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", coordinateCount % inDimension, coordinateCount/inDimension, 0, remainder.c_str()); + }else{ + point_coordinates.push_back(p); + coordinateCount++; + } + } + if(coordinateCount != inCount*inDimension){ + if(coordinateCount%inDimension==0){ + throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinateCount/inDimension)); + }else{ + throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinateCount%inDimension), coordinateCount/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(point_coordinates.size()+newCoordinates); + makeValid(); +}//reserveCoordinates + +#//Helpers + +int PointCoordinates:: +indexOffset(int i) const { + int n= i*dimension(); + int coordinateCount= point_coordinates.count(); + if(i<0 || n>coordinateCount){ + throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinateCount, i); + } + return n; +} + +}//namespace orgQhull + +#//Global functions + +using std::endl; +using std::ostream; + +using orgQhull::Coordinates; +using orgQhull::PointCoordinates; + +// FIXUP Almost the same as operator<< for RboxPoints +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/cpp/PointCoordinates.h b/cpp/PointCoordinates.h new file mode 100644 index 0000000..2b6e203 --- /dev/null +++ b/cpp/PointCoordinates.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/PointCoordinates.h#8 $$Change: 1094 $ +** $DateTime: 2009/11/24 20:04:16 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHPOINTCOORDINATES_H +#define QHPOINTCOORDINATES_H + +#include "QhullPoints.h" +#include "Coordinates.h" + +#include <ostream> +#include <vector> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! Zero or more points with Coordinates, count, and dimension + class PointCoordinates; + +class PointCoordinates : public QhullPoints { + +private: +#//Field + Coordinates point_coordinates; //! array of point coordinates + //! may have extraCoordinates() + std::string point_comment; //! Comment describing PointCoordinates + +public: +#//Construct + PointCoordinates(); + explicit PointCoordinates(int dimension); + explicit PointCoordinates(const std::string &comment); + PointCoordinates(int dimension, const std::string &comment); + PointCoordinates(int dimension, const std::string &comment, int coordinateCount, 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(); + +#//Convert + //! QhullPoints coordinates, constData, data, count, size +#ifndef QHULL_NO_STL + void append(const std::vector<coordT> &coordinates) { if(!coordinates.empty()){ append((int)coordinates.size(), &coordinates[0]); } } + std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); } +#endif //QHULL_NO_STL +#ifdef QHULL_USES_QT + void append(const QList<coordT> &coordinates) { if(!coordinates.isEmpty()){ append(coordinates.count(), &coordinates[0]); } } + QList<coordT> toQList() const { return point_coordinates.toQList(); } +#endif //QHULL_USES_QT + + +#//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 coordinateCount, coordT *c) { QhullPoints::defineAs(coordinateCount, c); } + //! defineAs() otherwise disabled +public: + +#//ElementAccess + //! See QhullPoints for at, back, first, front, last, mid, [], value + +#//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(); } + +#//Search + //! See QhullPoints for contains, count, indexOf, lastIndexOf + +#//Modify + void append(int count, 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) const; + 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); + +#//Helpers +private: + int indexOffset(int i) const; + +};//PointCoordinates + +}//namespace orgQhull + +#//Global functions + +std::ostream &operator<<(std::ostream &os, const orgQhull::PointCoordinates &p); + +#endif // QHPOINTCOORDINATES_H diff --git a/cpp/Qhull.cpp b/cpp/Qhull.cpp new file mode 100644 index 0000000..e6cdddb --- /dev/null +++ b/cpp/Qhull.cpp @@ -0,0 +1,476 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/Qhull.cpp#35 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ +** +****************************************************************************/ + +#//! Qhull -- invoke qhull from C++ +#//! Compile qhulllib and Qhull together due to use of setjmp/longjmp() + +#include <iostream> + +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "QhullFacetList.h" +#include "QhullQh.h" +#include "RboxPoints.h" +#include "UsingQhullLib.h" + +extern "C" { + #include "../src/qhull_a.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 + +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(UsingQhullLib::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) +{ + initializeQhull(); +}//Qhull + +Qhull:: +Qhull(const RboxPoints &points, const char *qhullCommand) +: qhull_qh(0) +, qhull_run_id(UsingQhullLib::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) +{ + initializeQhull(); + runQhull(points, qhullCommand); +}//Qhull rbox + +Qhull:: +Qhull(const char *rboxCommand, int pointDimension, int pointCount, const realT *points, const char *qhullCommand) +: qhull_qh(0) +, qhull_run_id(UsingQhullLib::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) +{ + initializeQhull(); + runQhull(rboxCommand, pointDimension, pointCount, points, qhullCommand); +}//Qhull points + + +void Qhull:: +initializeQhull() +{ + #if qh_QHpointer + qhull_qh= new QhullQh; + qhull_qh->old_qhstat= qh_qhstat; + qhull_qh->old_tempstack= static_cast<setT *>(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; +}//initializeQhull + +Qhull:: +~Qhull() throw() +{ + //! UsingQhullLib is required by ~QhullQh + UsingQhullLib 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= UsingQhullLib::NOqhRunId; + // Except for cerr, does not throw errors + if(hasQhullMessage()){ + cerr<<qhullMessage(); //FIXUP: where should error and log messages go on ~Qhull? + clearQhullMessage(); + } + } + maybeThrowQhullMessage(exitCode, QhullError::NOthrow); + } + s_qhull_output= 0; // Set by UsingQhullLib +}//~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 -- 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 + +//! Setup global state (qh_qh, qh_qhstat, qhmem.tempstack) +int Qhull:: +runId() +{ + UsingQhullLib u(this); + QHULL_UNUSED(u); + + return qhull_run_id; +}//runId + + +#//GetValue + +double Qhull:: +area(){ + UsingQhullLib q(this); + qhull_qh->checkIfQhullRan(); + 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(){ + UsingQhullLib q(this); + qhull_qh->checkIfQhullRan(); + 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 +QhullFacetList Qhull:: +facetList() const{ + return QhullFacetList(beginFacet(), endFacet()); +}//facetList + +QhullPoints Qhull:: +points() const +{ + return QhullPoints(dimension(), qhull_qh->num_points*dimension(), qhull_qh->first_point); +} + +QhullVertexList Qhull:: +vertexList() const{ + return QhullVertexList(beginVertex(), endVertex()); +}//vertexList + +#//Modify + +void Qhull:: +outputQhull() +{ + UsingQhullLib q(this); + qhull_qh->checkIfQhullRan(); + 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) +{ + UsingQhullLib q(this); + qhull_qh->checkIfQhullRan(); + 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)); + 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 &points, const char *qhullCommand) +{ + runQhull(points.comment().c_str(), points.dimension(), points.count(), &*points.coordinates(), qhullCommand); +}//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 *rboxCommand, int pointDimension, int pointCount, const realT *points, const char *qhullCommand) +{ + if(run_called){ + throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed."); + } + run_called= true; + string s("qhull "); + s += qhullCommand; + char *command= const_cast<char*>(s.c_str()); + UsingQhullLib 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, rboxCommand, sizeof( qh rbox_command)); + if(qh DELAUNAY){ + qh PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput() + } + pointT *newPoints= const_cast<pointT*>(points); + 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); + //FIXUP -- copy rbox_command here. SetCommandMessage is wrong + qh_qhull(); + qh_check_output(); + qh_prepare_output(); + if(qh VERIFYoutput && !qh STOPpoint && !qh STOPcone){ + qh_check_points(); + } + } + for(int k= qhull_dimension; k--; ){ + 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 copy constructor is expensive if logging + } +}//maybeThrowQhullMessage + +void Qhull:: +maybeThrowQhullMessage(int exitCode, int noThrow) throw() +{ + 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. + s_qhull_output == Qhull + +notes: + only called from qhulllib + 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: UsingQhullLib 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 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/cpp/Qhull.h b/cpp/Qhull.h new file mode 100644 index 0000000..9646c9f --- /dev/null +++ b/cpp/Qhull.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/Qhull.h#31 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$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> + +namespace orgQhull { + +/*** + Compile qhullcpp and qhulllib with the same compiler. setjmp() and longjmp() must be the same. +*/ + +#//Types + //! Qhull -- run Qhull from C++ + class Qhull; + + //Defined elsewhere + class QhullFacetList; + class RboxPoints; + +class Qhull { + +private: +#//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_POINTER) + 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 after runQhull. Error if call again. + bool qh_active; //! True if qh_qh is 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 UsingQhullLib; + +#//Attribute +public: + Coordinates feasiblePoint; //! feasible point for half-space intersection + bool useOutputStream; //! Set if using outputStream + // FIXUP feasiblePoint useOutputStream as field or getter? + +#//constructor, assignment, destructor, invariant + Qhull(); //! Qhull::runQhull() must be called next + Qhull(const RboxPoints &points, const char *qhullCommand); + Qhull(const char *rboxCommand, int pointDimension, int pointCount, const realT *points, const char *qhullCommand); + ~Qhull() throw(); +private: + void initializeQhull(); + Qhull(const Qhull&); //disabled + Qhull &operator=(const Qhull&); //disabled + +public: +#//virtual methods + //FIXUP -- qh_memfree, etc. as virtual? + +#//Messaging + // FIXUP rename as errorMessage? + 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); + +#//GetSet + bool defined() const { return qhull_dimension>0; } + int dimension() const { return qhull_dimension; } //FIXUP use dimension() instead? + // non-const due to QhullPoint + QhullPoint origin() { QHULL_ASSERT(run_called && origin_point.size()>0); return QhullPoint(dimension(), origin_point.data()); } + QhullQh *qhullQh() const { return qhull_qh; }; + int runId(); // Modifies my_qhull + +#//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; } + +#//GetValue + double area(); + double volume(); + +#//ForEach + QhullFacet beginFacet() const { return QhullFacet(qhull_qh->facet_list); } + QhullVertex beginVertex() const { return QhullVertex(qhull_qh->vertex_list); } + 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 { return QhullPointSet(dimension(), qhull_qh->other_points); } + //FIXUP -- replace pointCoordinateBegin with points()? + 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; + +#//Modify + void outputQhull(); + void outputQhull(const char * outputflags); + void runQhull(const RboxPoints &points, const char *qhullCommand); + void runQhull(const char *rboxCommand, int pointDimension, int pointCount, const realT *points, const char *qhullCommand); + +private: +#//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/cpp/QhullError.cpp b/cpp/QhullError.cpp new file mode 100644 index 0000000..3e2e656 --- /dev/null +++ b/cpp/QhullError.cpp @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2008 C. Bradford Barber. All rights reserved. +** +****************************************************************************/ + +#//! QhullError -- All exceptions thrown by Qhull are QhullErrors + +#include <iostream> +#include <memory> +#include <sstream> +#include <string> + +#include "QhullError.h" + +using std::cout; +using std::ostringstream; +using std::string; + +typedef std::auto_ptr<std::stringstream> StringStreamPointer; //! auto_ptr transfers ownership on copy + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//GetSet + +}//namespace orgQhull + diff --git a/cpp/QhullError.h b/cpp/QhullError.h new file mode 100644 index 0000000..a57ef39 --- /dev/null +++ b/cpp/QhullError.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullError.h#29 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLERROR_H +#define QHULLERROR_H + +#include "road/RoadError.h" + +#include <assert.h> +#include <stdexcept> +#include <string> + +namespace orgQhull { + +#//Types + //! QhullError -- std::exception class for Qhull + class QhullError; + +class QhullError : public RoadError { + +public: +#//Constants + enum { + QHULLfirstError= 10000, //Larger than msgcode in Qhull's user.h + QHULLlastError= 10067, + NOthrow= 1 //! For flag to UsingQhullLIb() + }; + +#//Constructors + // default constructors + QhullError() : RoadError() {}; + 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) {}; + +};//class QhullError + +#ifndef QHULL_1 + #define QHULL_ASSERT assert + + //! See Qt's qglobal.h + #if defined(Q_CC_INTEL) && !defined(Q_OS_WIN) // FIXUP + template <typename T> + inline void qUnused(T &x) { (void)x; } + # define QHULL_UNUSED(x) qUnused(x); + #else + # define QHULL_UNUSED(x) (void)x; + #endif +#endif + +}//namespace orgQhull + +#//Global functions + +inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os<< e.what(); } + +#endif // QHULLERROR_H diff --git a/cpp/QhullEvent.cpp b/cpp/QhullEvent.cpp new file mode 100644 index 0000000..850eabd --- /dev/null +++ b/cpp/QhullEvent.cpp @@ -0,0 +1,18 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2008 C. Bradford Barber. All rights reserved. +** +****************************************************************************/ + +#//! QhullEvent -- A recorded event in a circular buffer + +#include "QhullEvent.h" + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + + +}//namespace orgQhull + diff --git a/cpp/QhullEvent.h b/cpp/QhullEvent.h new file mode 100644 index 0000000..09efa17 --- /dev/null +++ b/cpp/QhullEvent.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullEvent.h#6 $$Change: 1053 $ +** $DateTime: 2009/10/02 22:00:28 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLEVENT_H +#define QHULLEVENT_H + +#include <string> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! QhullEvent -- Circular array of Qhull execution events + class QhullEvent; + +class QhullEvent { + +#//Types + friend class QhullLog; + +#//Constants +public: + enum EventTypes { + LogEvent= 0x0, + CallEvent= 0x1, + ReturnEvent= 0x2 + }; + +#//Fields +private: + unsigned int time_s:24; + unsigned int event_type:2; + unsigned int trace_level:3; + unsigned int unused_bits:3; + const char *event_message; + int int_arg1; + int int_arg2; + const char *cstr_arg3; + + +public: +#//Constructor, destructor + QhullEvent() : time_s(0), event_type(0), trace_level(0), unused_bits(0), event_message(0), int_arg1(0), int_arg2(0), cstr_arg3(0) {}; + QhullEvent(int timeSeconds, EventTypes e, int traceLevel, const char *message, int arg1, int arg2, const char *arg3) : time_s(timeSeconds), event_type(e), trace_level(traceLevel), unused_bits(0), event_message(message), int_arg1(arg1), int_arg2(arg2), cstr_arg3(arg3) {}; + ~QhullEvent() {}; +};//QhullEvent + +inline QhullEvent::EventTypes operator&(QhullEvent::EventTypes a, QhullEvent::EventTypes b) { return static_cast<QhullEvent::EventTypes>(int(a) & int(b)); }; + +#if 0 +error messages start with "Error" -- may be translated +.what is the last error message +messageLength() +on ERROR dump log to FILE +shadow log? +messageCount, maxCount +#endif + +}//namespace orgQhull + +#//Global functions + +#endif // QHULLEVENT_H diff --git a/cpp/QhullFacet.cpp b/cpp/QhullFacet.cpp new file mode 100644 index 0000000..9569454 --- /dev/null +++ b/cpp/QhullFacet.cpp @@ -0,0 +1,512 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullFacet.cpp#28 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class + +#include <ostream> + +#include "QhullError.h" +#include "QhullSet.h" +#include "QhullRidge.h" +#include "QhullFacet.h" +#include "QhullFacetSet.h" +#include "QhullPoint.h" +#include "QhullPointSet.h" +#include "QhullVertex.h" + +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= {}; + +#//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) +{ + UsingQhullLib 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){ + 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{ + UsingQhullLib 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{ + UsingQhullLib 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 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){ + UsingQhullLib 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::UsingQhullLib; + +ostream & +operator<<(ostream &os, const QhullFacet::PrintFacet &pr) // FIXUP make const (center) +{ + 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 qh_REAL_1 + } + }else{ + for(int k=0; k<numCoords; k++){ + os<< qh_INFINITE << " "; // FIXUP 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 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(); // FIXUP use QhullFacet for << + if(p.message){ + os<< p.message; + } + + os<< (f->toporient ? " top" : " bottom"); + if(f->simplicial){ + os<< " simplicial"; + } + if(f->tricoplanar){ + os<< " tricoplanar"; + } + if(f->upperdelaunay){ + 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 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 %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 %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 %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 %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==UsingQhullLib::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(pr.run_id!=UsingQhullLib::NOqhRunId){ + UsingQhullLib q(pr.run_id); + // No calls to qhulllib + 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; + } + }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(UsingQhullLib::NOqhRunId); + return os; +}//<< QhullFacet diff --git a/cpp/QhullFacet.h b/cpp/QhullFacet.h new file mode 100644 index 0000000..b85f695 --- /dev/null +++ b/cpp/QhullFacet.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullFacet.h#30 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLFACET_H +#define QHULLFACET_H + +#include "Coordinates.h" +#include "QhullHyperplane.h" +#include "QhullPoint.h" +#include "QhullSet.h" +#include "QhullPointSet.h" + +#include <string> +#include <vector> +#include <ostream> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//ClassRef + class QhullFacetSet; + class QhullRidge; + typedef QhullSet<QhullRidge> QhullRidgeSet; + class QhullVertex; + class QhullVertexSet; + +#//Types + //! QhullFacet -- Qhull's facet structure, facetT [qhulllib.h], as a C++ class + class QhullFacet; + +//! A QhullFacet is the C++ equivalent to Qhull's facetT* +class QhullFacet { + +#//Fields -- no additions (QhullFacetSet of facetT*) + facetT *qh_facet; //! May be 0 (!isDefined) for corner cases (e.g., *facetSet.end()==0) + +#//Class objects + static facetT s_empty_facet; // needed for shallow copy + +public: +#//Constants + +#//Constructors + QhullFacet() : qh_facet(&s_empty_facet) {} + //! Shallow copy + QhullFacet(const QhullFacet &o) : qh_facet(o.qh_facet ? o.qh_facet : &s_empty_facet) {} + QhullFacet &operator=(const QhullFacet &o) { qh_facet= o.qh_facet ? o.qh_facet : &s_empty_facet; return *this; } + ~QhullFacet() {} + +#//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; } + +#//QhullSet<QhullFacet> + facetT *getBaseT() const { return getFacetT(); } + +#//getSet + int dimension() const; + int id() const { return qh_facet ? qh_facet->id : -1; } + bool isDefined() const { return qh_facet && qh_facet != &s_empty_facet; } + bool isGood() const { return qh_facet && qh_facet->good; } + 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); } + QhullFacet previous() const { return qh_facet->previous; } + QhullFacet tricoplanarOwner() 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); } + QhullHyperplane innerplane(int qhRunId) const; + QhullHyperplane outerplane(int qhRunId) const; + QhullPoint voronoiVertex(int qhRunId); + +#//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); + +#//foreach + // Can not inline. Otherwise circular reference + QhullPointSet coplanarPoints() const; + QhullFacetSet neighborFacets() const; + QhullPointSet outsidePoints() const; + QhullRidgeSet ridges() const; + QhullVertexSet vertices() const; + +#//IO + struct PrintCenter{ + QhullFacet *facet; //! Not 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; //! FIXUP, 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; // Pointer to allow as subclass + 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; //! FIXUP, 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{ + 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 + +#//Global functions + +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); //FIXUP. No conversion! { os<< f.print(orgQhull::UsingQhullLib::NOqhRunId); return os; } // FIXUP non-const due to center. Make it mutable? + +#endif // QHULLFACET_H diff --git a/cpp/QhullFacetList.cpp b/cpp/QhullFacetList.cpp new file mode 100644 index 0000000..f2811ee --- /dev/null +++ b/cpp/QhullFacetList.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullFacetList.cpp#18 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$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 { + +#//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::UsingQhullLib; + +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 + + diff --git a/cpp/QhullFacetList.h b/cpp/QhullFacetList.h new file mode 100644 index 0000000..dbd253e --- /dev/null +++ b/cpp/QhullFacetList.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullFacetList.h#16 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLFACETLIST_H +#define QHULLFACETLIST_H + +#include "QhullLinkedList.h" + +#include <ostream> + +namespace orgQhull { + +#//ClassRef + class QhullFacet; + +#//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> { + +#// Fields +private: + bool select_all; //! True if include bad facets. Default is false. + +#//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. + QhullFacetList(const QhullFacetList &o) : QhullLinkedList<QhullFacet>(*o.begin(), *o.end()), select_all(o.select_all) {} + ~QhullFacetList() {} + +private: + //!Disable default constructor and copy assignment. See QhullSetBase + QhullFacetList(); + QhullFacetList &operator=(const QhullFacetList &); +public: + +#//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 + +#//GetSet + bool isSelectAll() const { return select_all; } + void selectAll() { select_all= true; } + void selectGood() { select_all= false; } + +#//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() + +#//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 + +#//== 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); + +// FIXUP -- why did <<facetList work and the others did not? +// print() not available since printVertices() requires qhRunId. +// [9/09] added const +inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList &fs) { os<< fs.printFacets(orgQhull::UsingQhullLib::NOqhRunId); return os; } + +#endif // QHULLFACETLIST_H diff --git a/cpp/QhullFacetSet.cpp b/cpp/QhullFacetSet.cpp new file mode 100644 index 0000000..a229f63 --- /dev/null +++ b/cpp/QhullFacetSet.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullFacetSet.cpp#15 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$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 { + +#//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::UsingQhullLib; + +ostream & +operator<<(ostream &os, const QhullFacetSet &fs) +{ + os<< fs.print(UsingQhullLib::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.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/cpp/QhullFacetSet.h b/cpp/QhullFacetSet.h new file mode 100644 index 0000000..7a0db93 --- /dev/null +++ b/cpp/QhullFacetSet.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullFacetSet.h#14 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLFACETSET_H +#define QHULLFACETSET_H + +#include "QhullSet.h" + +#include <ostream> + +namespace orgQhull { + +#//ClassRef + class QhullFacet; + +#//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> { + +#//Fields +private: + bool select_all; //! True if include bad facets. Default is false. + +#//Constructor +public: + //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. + 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: + +#//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 + +#//GetSet + bool isSelectAll() const { return select_all; } + void selectAll() { select_all= true; } + void selectGood() { select_all= false; } + +#//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() + +#//IO + // Not same as QhullFacetList#IO. A QhullFacetSet is a component of a QhullFacetList. + + struct PrintFacetSet{ + const QhullFacetSet *facet_set; // FIXUP should Print... use pointers? + const char *message; + int run_id; + PrintFacetSet(int qhRunId, const char *message, const QhullFacetSet *s) : facet_set(s), 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 *message; + PrintIdentifiers(const char *message, const QhullFacetSet *s) : facet_set(s), message(message) {} + };//PrintIdentifiers + PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); } + +};//class QhullFacetSet + +}//namespace orgQhull + +#//== Global namespace ========================================= + +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet &fs); // FIXUP no 'const ...PrintFacetSet as below! { os<< fs.print(orgQhull::UsingQhullLib::NOqhRunId, ""); } +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/cpp/QhullHyperplane.cpp b/cpp/QhullHyperplane.cpp new file mode 100644 index 0000000..b2166c1 --- /dev/null +++ b/cpp/QhullHyperplane.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullHyperplane.cpp#4 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> + +#include "QhullHyperplane.h" +#include "QhullPoint.h" + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//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= abs(hyperplane_offset-other.hyperplane_offset); + if(d>UsingQhullLib::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 > UsingQhullLib::globalAngleEpsilon()){ + return false; + } + return true; +}//operator== + +#//GetSet + +}//namespace orgQhull + +#//Global functions + +using std::ostream; +using orgQhull::QhullHyperplane; +using orgQhull::UsingQhullLib; + +#//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.hyperplane_message){ + os<< pr.hyperplane_message; + } + const realT *c= p.coordinates(); + for(int k=p.dimension(); k--; ){ + realT r= *c++; + if(pr.hyperplane_message){ + os<< " " << r; // FIXUP %8.4g + }else{ + os<< " " << r; // FIXUP 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/cpp/QhullHyperplane.h b/cpp/QhullHyperplane.h new file mode 100644 index 0000000..c1764a3 --- /dev/null +++ b/cpp/QhullHyperplane.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullHyperplane.h#4 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHHYPERPLANE_H +#define QHHYPERPLANE_H + +#include "QhullError.h" +#include "QhullIterator.h" +#include "UsingQhullLib.h" + +#include <ostream> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { +#//ClassRef + class QhullPoint; + +#//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: +#//Fields + coordT *hyperplane_coordinates; // Keep pointers aligned + int hyperplane_dimension; + coordT hyperplane_offset; + +public: +#//Types + typedef const coordT * iterator; + typedef const coordT * const_iterator; + typedef QhullHyperplane::iterator Iterator; + typedef QhullHyperplane::const_iterator ConstIterator; + +#//Construct + QhullHyperplane() : hyperplane_coordinates(0), hyperplane_dimension(0), hyperplane_offset(0.0) {}; + QhullHyperplane(int dimension, coordT *c, coordT offset) : hyperplane_coordinates(c), hyperplane_dimension(dimension), hyperplane_offset(offset) {} + // Creates an alias. Does not copy the point. Needed for 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 point. 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() {} + +#//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 + +#//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; } + +#//Define + void defineAs(int dimension, coordT *c, coordT offset) { QHULL_ASSERT(dimension>=0); hyperplane_coordinates= c; hyperplane_dimension= dimension; hyperplane_offset= offset; } + //! 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 dimension) { hyperplane_dimension= dimension; } + void setOffset(coordT c) { hyperplane_offset= c; } + +#//value + double distance(const QhullPoint &p) const; + double norm() const; + +#//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(); } + +#//Operator + bool operator==(const QhullHyperplane &other) const; + bool operator!=(const QhullHyperplane &other) const { return !operator==(other); } + const coordT &operator[](int index) const { QHULL_ASSERT(index>=0 && index<hyperplane_dimension); return *(hyperplane_coordinates+index); } + coordT &operator[](int index) { QHULL_ASSERT(index>=0 && index<hyperplane_dimension); return *(hyperplane_coordinates+index); } + +#//IO + struct PrintHyperplane{ + const QhullHyperplane *hyperplane; //! FIXUP elsewhere. const is OK now + const char *hyperplane_message; + const char *hyperplane_offset_message; + PrintHyperplane(const char *message, const char *offsetMessage, const QhullHyperplane &p) : hyperplane(&p), hyperplane_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 + +#//Global functions + +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane::PrintHyperplane &pr); +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p); //FIXUP -- multiple instances if define here + +#endif // QHHYPERPLANE_H + diff --git a/cpp/QhullIterator.h b/cpp/QhullIterator.h new file mode 100644 index 0000000..6475846 --- /dev/null +++ b/cpp/QhullIterator.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullIterator.h#16 $$Change: 1059 $ +** $DateTime: 2009/10/30 18:26:26 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLITERATOR_H +#define QHULLITERATOR_H + +#include <assert.h> +#include <string> +#include <vector> +//! Avoid dependence on <iterator> +namespace std { struct bidirectional_iterator_tag; struct random_access_iterator_tag; } + +extern "C" { +#include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//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/cpp/QhullLinkedList.h b/cpp/QhullLinkedList.h new file mode 100644 index 0000000..7bba491 --- /dev/null +++ b/cpp/QhullLinkedList.h @@ -0,0 +1,369 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullLinkedList.h#24 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$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 { + +#//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. + //! qhulllib owns the contents. + //! QhullLinkedList does not define erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() + //! Derived from Qt/core/tools/qlinkedlist.h and qhulllib.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: +#//Fields + T begin_node; + T end_node; //! Sentinel node at end of list + +public: +#//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; + +#//Constructors + QhullLinkedList<T>(T b, T e) : begin_node(b), end_node(e) {} + 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: + +#//Conversions +#ifndef QHULL_NO_STL + std::vector<T> toStdVector() const; +#endif +#ifdef QHULL_USES_QT + QList<T> toQList() const; +#endif + +#//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(); } + +#//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(); } + +#//Modify -- Allocation of opaque types not implemented. + +#//Search + bool contains(const T &t) const; + int count(const T &t) const; + +#//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 { + public: + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef T value_type; + + T i; + + 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 { + public: + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef const T *pointer; + typedef const T &reference; + typedef T value_type; + + T i; + + 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 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 + +#//== Definitions ========================================= + +#//Conversion + +#ifndef QHULL_NO_STL +template <typename T> +std::vector<T> QhullLinkedList<T>:: +toStdVector() const +{ + std::vector<T> tmp; + 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 + +#//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 + +#//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== + +#//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+ + +#//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 + +#//Global functions + +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/cpp/QhullLog.cpp b/cpp/QhullLog.cpp new file mode 100644 index 0000000..abf03b4 --- /dev/null +++ b/cpp/QhullLog.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullLog.cpp#6 $$Change: 1053 $ +** $DateTime: 2009/10/02 22:00:28 $$Author: bbarber $ +** +****************************************************************************/ + +#//! QhullLog -- A recorded event in a circular buffer + +#include <time.h> + +#include "QhullLog.h" + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//Class global +std::vector<std::string> a_log; +std::vector<QhullEvent> a_events; +int a_head= 0; +int a_tail= 0; +int a_head_gap= 0; +int a_tail_end= 0; +int a_max_overrun= 0; +int a_call_depth= 0; +int a_min_call_depth= 0; +time_t a_start_time_s= 0; +int a_logging_enabled= 0; + +#//Constructor, destructor, etc. +QhullLog:: +QhullLog(int level, const char *message) +{ + a_call_depth++; + log(QhullEvent::CallEvent, level, message, 0, 0, 0); +} + +QhullLog:: +QhullLog(int level, const char *message, int arg1) +{ + a_call_depth++; + log(QhullEvent::CallEvent, level, message, arg1, 0, 0); +} + +QhullLog:: +QhullLog(int level, const char *message, int arg1, int arg2) +{ + a_call_depth++; + log(QhullEvent::CallEvent, level, message, arg1, arg2, 0); +} + +QhullLog:: +QhullLog(int level, const char *message, int arg1, const char* arg3) +{ + a_call_depth++; + log(QhullEvent::CallEvent, level, message, arg1, 0, arg3); +} + +QhullLog:: +QhullLog(int traceLevel, const char *message, int arg1, int arg2, const char* arg3) +{ + a_call_depth++; + log(QhullEvent::CallEvent, traceLevel, message, arg1, arg2, arg3); +} + +QhullLog:: +~QhullLog() +{ + if(--a_call_depth < a_min_call_depth){ + a_min_call_depth= a_call_depth; + } + if(a_events[a_tail].event_type & QhullEvent::ReturnEvent){ + log(QhullEvent::ReturnEvent, 0, 0, 0, 0, 0); + }else{ + a_events[a_tail++].event_type |= QhullEvent::ReturnEvent; + } +} + +#//GetSet + +#//Modify + +void QhullLog:: +log(int level, const char *message) +{ + log(QhullEvent::LogEvent, level, message, 0, 0, 0); +} + +void QhullLog:: +log(int level, const char *message, int arg1) +{ + log(QhullEvent::LogEvent, level, message, arg1, 0, 0); +} + +void QhullLog:: +log(int level, const char *message, int arg1, int arg2) +{ + log(QhullEvent::LogEvent, level, message, arg1, arg2, 0); +} + +void QhullLog:: +log(int level, const char *message, int arg1, const char* arg3) +{ + log(QhullEvent::LogEvent, level, message, arg1, 0, arg3); +} + + +#//Helper + +void QhullLog:: +cullEvents() +{ + +}//cullEvents + +//! May be called by multiple threads +void QhullLog:: +log(QhullEvent::EventTypes e, int traceLevel, const char *message, int arg1, int arg2, const char* arg3) +{ + traceLevel= traceLevel; // Ignore traceLevel for now + if(a_logging_enabled != 1){ + return; + } + int t= (int)(time(0) - a_start_time_s); // Conversion OK, seconds since starts + a_events[a_tail++]= QhullEvent(t, e, traceLevel, message, arg1, arg2, arg3); + a_call_depth++; + if(a_tail-a_head_gap < a_head || a_tail >= a_tail_end){ + maybeCullEvents(); + } +} + +void QhullLog:: +maybeCullEvents() +{ + if(a_tail>=a_tail_end){ + if(a_tail-a_tail_end > a_max_overrun){ + a_max_overrun= a_tail-a_tail_end; //FIXUP -- race condition + } + a_tail= 0; + } + if(a_head<a_head_gap){ + if(a_tail<a_head_gap || a_tail_end-a_tail+a_head < a_head_gap){ + cullEvents(); + } + }else if(a_head>a_tail && a_head-a_tail < a_head_gap){ + cullEvents(); + } +}//maybeCullEvents + + +}//namespace orgQhull + diff --git a/cpp/QhullLog.h b/cpp/QhullLog.h new file mode 100644 index 0000000..c36edc5 --- /dev/null +++ b/cpp/QhullLog.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullLog.h#8 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLLOG_H +#define QHULLLOG_H + +#include "QhullEvent.h" + +#include <string> +#include <vector> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! QhullLog -- Report errors in Qhull + class QhullLog; + +class QhullLog { + +#//Fields + +public: +#//Constants + +#//Class global + static std::vector<std::string> + a_log; + static std::vector<QhullEvent> + a_events; + static int a_head; //! Head of event queue. Multiple threads may simultaneously increment a_head + static int a_tail; //! Tail of event queue. + + static int a_head_gap; //! Gap between tail and head. + static int a_tail_end; //! End of event queue. Additional elements allocated to avoid buffer overflow + static int a_max_overrun; //! Maximum overrun due to multiple threads (a_head-a_end) + + static int a_call_depth; //! Current call depth + static int a_min_call_depth; //! Minimum call depth since last cull + + static time_t a_start_time_s; //! UTC seconds at start of logging + static int a_logging_enabled; //! True only if '1' + +#//Constructors + QhullLog(int level, const char *message); + QhullLog(int level, const char *message, int arg1); + QhullLog(int level, const char *message, int arg1, int arg2); + QhullLog(int level, const char *message, int arg1, const char *arg3); + QhullLog(int level, const char *message, int arg1, int arg2, const char *arg3); + ~QhullLog(); + +private: + QhullLog() {}; // disabled + +#//Update + void log(int level, const char *message); + void log(int level, const char *message, int arg1); + void log(int level, const char *message, int arg1, const char *arg3); + void log(int level, const char *message, int arg1, int arg2); + void log(int level, const char *message, int arg1, int arg2, const char *arg3); + +#//Helper +private: + void cullEvents(); + void log(QhullEvent::EventTypes t, int level, const char *message, int arg1, int arg2, const char *arg3); + void maybeCullEvents(); + +};//QhullLog + +#if 0 +.what is the last error message +.where is the stack + execution log +messageLength() +on ERROR dump log to FILE +log all the time +shadow log? +elide history RELATIVE level, n-back +messageCount, maxCount +#endif + + +}//namespace orgQhull + +#//Global functions + +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullLog *f); + +#endif // QHULLLOG_H diff --git a/cpp/QhullPoint.cpp b/cpp/QhullPoint.cpp new file mode 100644 index 0000000..1073f12 --- /dev/null +++ b/cpp/QhullPoint.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullPoint.cpp#21 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#include <algorithm> +#include <iostream> + +#include "QhullPoint.h" +#include "UsingQhullLib.h" + +#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) +{ + if(UsingQhullLib::hasPoints()){ + if(qhRunId==UsingQhullLib::NOqhRunId){ + const coordT *pointsEnd; + int dimension; + const coordT *points= UsingQhullLib::globalPoints(&dimension, &pointsEnd); + if(c>=points && c<pointsEnd){ + int offset= (int)(c-points); // WARN64 + return offset/dimension; + } + }else{ + UsingQhullLib 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 + +#//Operator + +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; + } + double epsilon= UsingQhullLib::globalDistanceEpsilon(); + // std::cout<< "FIXUP dist2 " << dist2 << " epsilon^2 " << epsilon*epsilon << std::endl; + return (dist2<=(epsilon*epsilon)); +}//operator== + + +#//Value + +//! Return distance betweeen 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::UsingQhullLib; + +#//operator<< + +ostream & +operator<<(ostream &os, const QhullPoint &p) +{ + os<< p.printWithIdentifier(UsingQhullLib::NOqhRunId, ""); + return os; +} + +//! Same as qh_printpointid [io.c] +ostream & +operator<<(ostream &os, const QhullPoint::PrintPoint &pr) +{ + QhullPoint p= *pr.point; // FIXUP null 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 %8.4g + }else{ + os<< " " << r; // FIXUP qh_REAL_1 + } + } + os<< std::endl; + return os; +}//printPoint + diff --git a/cpp/QhullPoint.h b/cpp/QhullPoint.h new file mode 100644 index 0000000..514df4e --- /dev/null +++ b/cpp/QhullPoint.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullPoint.h#24 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHPOINT_H +#define QHPOINT_H + +#include "QhullError.h" +#include "QhullIterator.h" +#include "UsingQhullLib.h" +#include "Coordinates.h" + +#include <ostream> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! QhullPoint as a pointer and dimension to shared memory + class QhullPoint; + //! Java-style iterator for QhullPoint coordinates + class QhullPointIterator; + +class QhullPoint { + +#//Class objects + //! QhullPoint and UsingQhullLib store QhullQh fields + +#//Class methods -- Convert point to id w/o QhullQh data structure +public: + static int id(const coordT *c) { return QhullPoint::id(UsingQhullLib::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); + +private: +#//Fields + coordT *point_coordinates; // Keep pointers aligned + int point_dimension; + //FIXUP C2063: 'operator<<' : not a function + //friend std::ostream & ::operator<<(std::ostream &os, QhullPoint &p); + //FIXUP QhullFacet_test.cpp error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'orgQhull::Coordinates' + //friend std::ostream &operator<<(std::ostream &os, QhullPoint &p); + +public: +#//Types + // A point is a pointer into an array of coordinates. + typedef const coordT * iterator; + typedef const coordT * const_iterator; + typedef QhullPoint::iterator Iterator; + typedef QhullPoint::const_iterator ConstIterator; + +#//Construct + QhullPoint() : point_coordinates(0), point_dimension(0) {}; + QhullPoint(int dimension, coordT *c) : point_coordinates(c), point_dimension(dimension) {} + explicit QhullPoint(Coordinates &c) : point_coordinates(c.data()), point_dimension(c.count()) {} + // Creates an alias. Does not copy the point. Needed for 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() {} + +#//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 + +#//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(UsingQhullLib::NOqhRunId, dimension(), coordinates()); } + bool isDefined() const { return point_coordinates!=0 && point_dimension>0; } + +#//Define + void advancePoint(int index) { point_coordinates += index*point_dimension; } + void defineAs(int dimension, coordT *c) { QHULL_ASSERT(dimension>=0); point_coordinates= c; point_dimension= dimension; } + //! 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 dimension) { point_dimension= dimension; } + +#//value + double distance(const QhullPoint &p) const; + +#//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(); } + +#//Operator + bool operator==(const QhullPoint &other) const; + bool operator!=(const QhullPoint &other) const { return !operator==(other); } + const coordT &operator[](int index) const { QHULL_ASSERT(index>=0 && index<point_dimension); return *(point_coordinates+index); } + coordT &operator[](int index) { QHULL_ASSERT(index>=0 && index<point_dimension); return *(point_coordinates+index); } + + struct PrintPoint{ + const QhullPoint *point; //! FIXUP elsewhere. const is OK now + 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(UsingQhullLib::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 + +#//Global functions + +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint::PrintPoint &pr); +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint &p); // FIXUP OK in c program but not inline { os<< p.print(orgQhull::UsingQhullLib::NOqhRunId, ""); return os; } + +#endif // QHPOINT_H + diff --git a/cpp/QhullPointSet.cpp b/cpp/QhullPointSet.cpp new file mode 100644 index 0000000..614751f --- /dev/null +++ b/cpp/QhullPointSet.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 c-> Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullPointSet.cpp#3 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#include <algorithm> +#include <iostream> + +#include "QhullPointSet.h" + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//Element-access +//! Derived from QhullSet::value +QhullPoint QhullPointSet:: +value(int index) const +{ + // Avoid call to qh_setsize() and assert in elementPointer() + //const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), index)); + void **n= reinterpret_cast<void **>(&SETelem_(getSetT(), index)); + coordT **n2= reinterpret_cast<coordT **>(n); + if(index>=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 index, QhullPoint &defaultValue) const +{ + // Avoid call to qh_setsize() and assert in elementPointer() + void **n= reinterpret_cast<void **>(&SETelem_(getSetT(), index)); + coordT **n2= reinterpret_cast<coordT **>(n); + if(index>=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 index= 0; + QhullPointSetIterator i(*this); + while(i.hasNext()){ + if(i.next()==t){ + return index; + } + ++index; + } + return -1; +}//indexOf + +int QhullPointSet:: +lastIndexOf(const QhullPoint &t) const +{ + int index= count()-1; + QhullPointSetIterator i(*this); + i.toBack(); + while(i.hasPrevious()){ + if(i.previous()==t){ + break; + } + --index; + } + return index; +}//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::UsingQhullLib; + +#//operator<< + +ostream & +operator<<(ostream &os, const QhullPointSet &ps) +{ + os<< ps.print(UsingQhullLib::NOqhRunId); + return os; +}//<<QhullPointSet + +ostream & +operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr) +{ + const QhullPointSet s= *pr.point_set; + if (pr.message) { + os<< pr.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.message) { + os<< pr.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/cpp/QhullPointSet.h b/cpp/QhullPointSet.h new file mode 100644 index 0000000..6967927 --- /dev/null +++ b/cpp/QhullPointSet.h @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullPointSet.h#11 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLPOINTSET_H +#define QHULLPOINTSET_H + +#include "QhullSet.h" +#include "QhullPoint.h" +#include <ostream> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! QhullPointSet -- a set of coordinate pointers with dimension + // with const_iterator and iterator + class QhullPointSet; + //! Java-style iterator + class QhullPointsIterator; + +#//Classref + class QhullPoint; + +class QhullPointSet : public QhullSet<coordT *> { + +#//Types +public: + class const_iterator; + class iterator; + typedef QhullPointSet::const_iterator ConstIterator; + typedef QhullPointSet::iterator Iterator; + + typedef ptrdiff_t difference_type; + typedef int size_type; + typedef QhullPoint value_type; + //typedef const value_type *const_pointer; // FIXUP: Pointers and reference types not available due to missing dimension + //typedef const value_type &const_reference; + //typedef value_type *pointer; + //typedef value_type &reference; + +#//Field +private: + int point_dimension; + +#//Construct +public: + //Conversion from setT* is not type-safe. Implicit conversion for void* to T + QhullPointSet(int dimension, setT *s) : QhullSet<coordT *>(s), point_dimension(dimension) {} + //Copy constructor copies pointer but not contents. Needed for return by value. + QhullPointSet(const QhullPointSet &o) : QhullSet<coordT *>(o), point_dimension(o.point_dimension) {} + +//disabled since p= p2 is ambiguous (coord* vs coord) +private: + QhullPointSet(); + QhullPointSet &operator=(const QhullPointSet &); +public: + +#//Conversions + // inherited -- constData, data +#ifndef QHULL_NO_STL + std::vector<QhullPoint> toStdVector() const; +#endif +#ifdef QHULL_USES_QT + QList<QhullPoint> toQList() const; +#endif + +#//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); } + +#//Element access -- can not return references since QhullPoint must be generated + QhullPoint at(int index) const { return operator[](index); } + 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 index) const { return QhullPoint(dimension(), QhullSet<coordT *>::operator[](index)); } + QhullPoint second() const { return operator[](1); } + QhullPoint value(int index) const; + // Non-const since copy is an alias + QhullPoint value(int index, QhullPoint &defaultValue) const; + +#//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 + +#//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 index) { return QhullPoint(point_dimension, *(i+index)); } + 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 ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; + typedef QhullPoint *pointer; + typedef QhullPoint &reference; + typedef QhullPoint value_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 index) { return QhullPoint(point_dimension, *(i+index)); } + //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 + +#//IO + struct PrintIdentifiers{ + const QhullPointSet *point_set; // FIXUP should Print... use pointers? + const char *message; + int run_id; + PrintIdentifiers(const char *message, const QhullPointSet *s) : point_set(s), message(message) {} + };//PrintIdentifiers + PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); } + + struct PrintPointSet{ + const QhullPointSet *point_set; // FIXUP should Print... use pointers? + const char *message; + int run_id; + PrintPointSet(int qhRunId, const char *message, const QhullPointSet &s) : point_set(&s), 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 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 + +#//Global functions + +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/cpp/QhullPoints.cpp b/cpp/QhullPoints.cpp new file mode 100644 index 0000000..bc34c67 --- /dev/null +++ b/cpp/QhullPoints.cpp @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullPoints.cpp#13 $$Change: 1094 $ +** $DateTime: 2009/11/24 20:04:16 $$Author: bbarber $ +** +****************************************************************************/ + +#include <algorithm> +#include <iostream> + +#include "QhullPoints.h" + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//Read-only + +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 index, int length) const +{ + int n= count(); + if(index<0 || index>=n){ + n= 0; + }else if(length<0 || index+length>=n){ + n -= index; + }else{ + n -= index+length; + } + return QhullPoints(point_dimension, n*point_dimension, point_first+index*point_dimension); +}//mid + +QhullPoint QhullPoints:: +value(int index) const +{ + QhullPoint p; + if(index>=0 && index<count()){ + p.defineAs(point_dimension, point_first+index*point_dimension); + } + return p; +}//value + +QhullPoint QhullPoints:: +value(int index, QhullPoint &defaultValue) const +{ + QhullPoint p; + if(index>=0 && index<count()){ + p.defineAs(point_dimension, point_first+index*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 *coordinates) const +{ + if(!includesCoordinates(coordinates) || dimension()==0){ + return -1; + } + size_t offset= coordinates-point_first; + int index= (int)offset/dimension(); // int for error reporting + int extra= (int)offset%dimension(); + if(extra!=0){ + throw QhullError(10066, "Qhull error: coordinates %x are not at point boundary (extra %d at index %d)", extra, index, 0.0, coordinates); + } + return index; +}//indexOf coordT + +int QhullPoints:: +indexOf(const coordT *coordinates, int noThrow) const +{ + size_t extra= 0; + if(noThrow){ + if(!includesCoordinates(coordinates)||dimension()==0){ + return -1; + } + extra= (coordinates-point_first)%dimension(); + } + return indexOf(coordinates-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/cpp/QhullPoints.h b/cpp/QhullPoints.h new file mode 100644 index 0000000..1d758f9 --- /dev/null +++ b/cpp/QhullPoints.h @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullPoints.h#19 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLPOINTS_H +#define QHULLPOINTS_H + +#include "QhullPoint.h" +#include <ostream> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//Types + //! coordinate pointer with dimension + // with const_iterator and iterator + class QhullPoints; + //! Java-style iterator + class QhullPointsIterator; + +class QhullPoints { + +public: +#//Types + // QhullPoints consists of pointers into an array of coordinates. + class const_iterator; + class iterator; + typedef QhullPoints::const_iterator ConstIterator; + typedef QhullPoints::iterator Iterator; + +#//Field + coordT *point_first; + coordT *point_end; // end>=first. Trailing coordinates ignored + int point_dimension; // >= 0 + +public: +#//Construct + QhullPoints() : point_first(0), point_end(0), point_dimension(0) {}; + QhullPoints(int dimension) : point_first(0), point_end(0), point_dimension(dimension) { QHULL_ASSERT(dimension>=0); } + QhullPoints(int dimension, int coordinateCount, coordT *c) : point_first(c), point_end(c+coordinateCount), point_dimension(dimension) { QHULL_ASSERT(dimension>=0 && coordinateCount>=0 ); } + 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: +#//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 + +#//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 dimension, int coordinateCount, coordT *c) { QHULL_ASSERT(dimension>=0 && coordinateCount>=0 && c!=0); point_first= c; point_end= c+coordinateCount; point_dimension= dimension; } + void defineAs(int coordinateCount, coordT *c) { QHULL_ASSERT((coordinateCount>=0 && c!=0) || (c==0 && coordinateCount==0)); point_first= c; point_end= c+coordinateCount; } + 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)%point_dimension : 0; } // WARN64 + bool includesCoordinates(const coordT *coordinates) const { return coordinates>=point_first && coordinates<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 dimension) { QHULL_ASSERT(dimension>=0); point_dimension= dimension; } + size_t size() const { return (point_dimension ? (point_end-point_first)/point_dimension : 0); } + +#//ElementAccess -- can not return references to QhullPoint + QhullPoint at(int index) const { coordT *p= point_first+index*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 index, int length= -1) const; + QhullPoint operator[](int index) const { return at(index); } + QhullPoint value(int index) const; + // Non-const since copy is an alias + QhullPoint value(int index, QhullPoint &defaultValue) const; + +#//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); } + +#//Search + bool contains(const QhullPoint &t) const; + int count(const QhullPoint &t) const; + int indexOf(const coordT *coordinates) const; + int indexOf(const coordT *coordinates, int noThrow) const; + int indexOf(const QhullPoint &t) const; + int lastIndexOf(const QhullPoint &t) const; + +#//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 ptrdiff_t difference_type; + typedef QhullPoint value_type; + typedef QhullPoint *pointer; + typedef QhullPoint &reference; + + iterator() : QhullPoint() {} + iterator(const iterator &o): QhullPoint(*o) {} + explicit iterator(const QhullPoints &ps) : QhullPoint(ps.dimension(), ps.coordinates()) {} + explicit iterator(int dimension, coordT *c): QhullPoint(dimension, c) {} + iterator &operator=(const iterator &o) { defineAs( const_cast<iterator &>(o)); return *this; } + QhullPoint *operator->() { return this; } + // value instead of reference since advancePoint() modifies self + QhullPoint operator*() const { return *this; } + QhullPoint operator[](int index) const { QhullPoint n= *this; n.advancePoint(index); return n; } + bool operator==(const iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates()==o.coordinates(); } + bool operator!=(const iterator &o) const { return !operator==(o); } + bool operator<(const iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() < o.coordinates(); } + bool operator<=(const iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() <= o.coordinates(); } + bool operator>(const iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() > o.coordinates(); } + bool operator>=(const iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() >= o.coordinates(); } + // reinterpret_cast to break circular dependency + bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(o).dimension()); return coordinates()==reinterpret_cast<const iterator &>(o).coordinates(); } + 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(dimension()==reinterpret_cast<const iterator &>(o).dimension()); return coordinates() < reinterpret_cast<const iterator &>(o).coordinates(); } + bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(o).dimension()); return coordinates() <= reinterpret_cast<const iterator &>(o).coordinates(); } + bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(o).dimension()); return coordinates() > reinterpret_cast<const iterator &>(o).coordinates(); } + bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(dimension()==reinterpret_cast<const iterator &>(o).dimension()); return coordinates() >= reinterpret_cast<const iterator &>(o).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 index) { advancePoint(index); return *this; } + iterator &operator-=(int index) { advancePoint(-index); return *this; } + iterator operator+(int index) const { iterator n= *this; n.advancePoint(index); return n; } + iterator operator-(int index) const { iterator n= *this; n.advancePoint(-index); return n; } + difference_type operator-(iterator o) const { QHULL_ASSERT(dimension()==o.dimension()); return (coordinates()-o.coordinates())/dimension(); } + };//QhullPoints::iterator + +#//QhullPoints::const_iterator //FIXUP what does const_... mean? + class const_iterator : public QhullPoint { + + public: + typedef std::random_access_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + typedef QhullPoint *pointer; + typedef QhullPoint &reference; + typedef QhullPoint value_type; + + const_iterator() : QhullPoint() {} + const_iterator(const const_iterator &o) : QhullPoint(*o) {} + const_iterator(QhullPoints::iterator &o) : QhullPoint(*o) {} + explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.dimension(), ps.coordinates()) {} + explicit const_iterator(int dimension, coordT *c): QhullPoint(dimension, c) {} + 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[](int index) const { QhullPoint n= *this; n.advancePoint(index); return n; } + bool operator==(const const_iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates()==o.coordinates(); } + bool operator!=(const const_iterator &o) const { return !operator==(o); } + bool operator<(const const_iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() < o.coordinates(); } + bool operator<=(const const_iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() <= o.coordinates(); } + bool operator>(const const_iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() > o.coordinates(); } + bool operator>=(const const_iterator &o) const { QHULL_ASSERT(dimension()==o.dimension()); return coordinates() >= o.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 index) { advancePoint(index); return *this; } + const_iterator &operator-=(int index) { advancePoint(-index); return *this; } + const_iterator operator+(int index) const { const_iterator n= *this; n.advancePoint(index); return n; } + const_iterator operator-(int index) const { const_iterator n= *this; n.advancePoint(-index); return n; } + difference_type operator-(const_iterator o) const { QHULL_ASSERT(dimension()==o.dimension()); return (coordinates()-o.coordinates())/dimension(); } + };//QhullPoints::const_iterator + +#//IO + struct PrintPoints{ + const QhullPoints *points; //! FIXUP elsewhere. const is OK now + 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(UsingQhullLib::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 + +// FIXUP -- can't use macro because next(),etc would return a reference to a temporary -- QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullPoints, QhullPoint) +class QhullPointsIterator +{ + typedef QhullPoints::const_iterator const_iterator; +#//Fields + const QhullPoints *ps; + const_iterator i; + +public: + QhullPointsIterator(const QhullPoints &o) : ps(&o), i(ps->constBegin()) {} + QhullPointsIterator &operator=(const QhullPoints &o) { ps = &o; 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 + +#//Global functions + +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/cpp/QhullQh.cpp b/cpp/QhullQh.cpp new file mode 100644 index 0000000..f7444ef --- /dev/null +++ b/cpp/QhullQh.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullQh.cpp#19 $$Change: 1053 $ +** $DateTime: 2009/10/02 22:00:28 $$Author: bbarber $ +** +****************************************************************************/ + +#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class + + +#include <iostream> +#include <sstream> + +#include "QhullError.h" +#include "QhullQh.h" +#include "QhullStat.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 + +#//Constructor, destructor, etc. + +//! If qh_QHpointer==0, invoke with placement new on qh_qh; +//! Sets qh_qh and qh_qhstat. Need to reset before UsingQhullLib. +//! 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 UsingQhullLib() 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= static_cast<setT *>(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 + +//! UsingQhullLib 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 UsingQhullLib?", 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 UsingQhullLib. 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 UsingQhullLib. 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 + +void QhullQh:: +errorAnotherUser() +{ +#if qh_QHpointer + if(qh_qh==0){ + throw QhullError(10019, "Qhull error: qhull was freed by another caller. It did not call stopQhullAccess()."); + } + if(qh_qh!=0 && qh_qh!=static_cast<qhT*>(this)){ + throw QhullError(10020, "Qhull error: qhull is already in use by another instance (run %d qh_qh %x)", qh run_id, 0, 0, qh_qh); + } +#endif +}//errorAnotherUser + +void QhullQh:: +checkIfQhullRan() // FIXUP -- use successful runQhull instead of TEMPsize? Many calls OK even if runQhull error'd +{ + if(qh TEMPsize==0){ // qh_initqhull_buffers() not called + throw QhullError(10023, "Qhull error: output does not exist. Call runQhull() first."); + } +}//checkIfQhullRan + +void QhullQh:: +startQhullAccess() +{ +# if qh_QHpointer + if(qh_qh){ + errorAnotherUser(); + }else{ + qh_qh= this; + } +# else + errorAnotherUser(); +# endif +}//startQhullAccess + +void QhullQh:: +stopQhullAccess() +{ +# if qh_QHpointer + if(qh_qh){ + errorAnotherUser(); + qh_qh= 0; + } +# else + errorAnotherUser(); +# endif +}//stopQhullAccess + +}//namespace orgQhull + diff --git a/cpp/QhullQh.h b/cpp/QhullQh.h new file mode 100644 index 0000000..fcd1a0c --- /dev/null +++ b/cpp/QhullQh.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullQh.h#14 $$Change: 1053 $ +** $DateTime: 2009/10/02 22:00:28 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLQH_H +#define QHULLQH_H + +#include <string> +#include <vector> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//defined here + //! QhullQh -- Qhull's global data structure, qhT, as a C++ class + //! See UsingQhullLib.h for C++/C interface to qhT + class QhullQh; + +class QhullQh : public qhT { + +#//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 + +#//members (empty) -- POD type equivalent to qhT. No data or virtual members + +public: +#//constructor, assignment, destructor, invariant + QhullQh(); + ~QhullQh(); + +private: + //!disable copy constructor and assignment + QhullQh(const QhullQh &); + QhullQh &operator=(const QhullQh &); + +public: +#//Access + void checkIfQhullRan(); + void errorAnotherUser(); + void startQhullAccess(); + void stopQhullAccess(); +};//class QhullQh + +}//namespace orgQhull + +#endif // QHULLQH_H diff --git a/cpp/QhullRidge.cpp b/cpp/QhullRidge.cpp new file mode 100644 index 0000000..68788ff --- /dev/null +++ b/cpp/QhullRidge.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullRidge.cpp#11 $$Change: 1052 $ +** $DateTime: 2009/09/27 23:20:48 $$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= {}; + +#//Constructor, destructor, etc. + +#//Accessors +//! Return next ridge and optional vertex for a 3d facet and ridge +//! Returns !isDefined() if no more ridges +//! 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::UsingQhullLib; + +ostream & +operator<<(ostream &os, const QhullRidge &r) +{ + os<< r.print(UsingQhullLib::NOqhRunId); + return os; +}//<< QhullRidge + +//! Duplicate of qh_printridge [io.c] +//! if pr.run_id==UsingQhullLib::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:"); + //FIXUP -- what if top or bottom are NULL? + if(r.getRidgeT()->top && r.getRidgeT()->bottom){ + os<< " between f" << r.topFacet().id() << " and f" << r.bottomFacet().id() << endl; + } + return os; +}//<< PrintRidge diff --git a/cpp/QhullRidge.h b/cpp/QhullRidge.h new file mode 100644 index 0000000..e76a3e5 --- /dev/null +++ b/cpp/QhullRidge.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullRidge.h#17 $$Change: 1098 $ +** $DateTime: 2009/12/04 22:47:59 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLRIDGE_H +#define QHULLRIDGE_H + +#include "QhullSet.h" +#include "QhullVertex.h" +#include "QhullVertexSet.h" +#include "QhullFacet.h" +#include <ostream> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//ClassRef + class QhullVertex; + class QhullVertexSet; + class QhullFacet; + +#//Types + //! QhullRidge -- Qhull's ridge structure, ridgeT [qhulllib.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 { + +#//Fields + ridgeT *qh_ridge; + +#//Class objects + static ridgeT s_empty_ridge; + +public: +#//Constants + +#//Constructors + QhullRidge() : qh_ridge(&s_empty_ridge) {} + //! Shallow copy + QhullRidge(const QhullRidge &o) : qh_ridge(o.qh_ridge) {} + QhullRidge &operator=(const QhullRidge &o) { qh_ridge= o.qh_ridge; return *this; } + ~QhullRidge() {} + +#//Conversion + //Implicit conversion from ridgeT + QhullRidge(ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge) {} + ridgeT *getRidgeT() const { return qh_ridge; } + +#//QhullSet<QhullRidge> + ridgeT *getBaseT() const { return getRidgeT(); } + +#//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); } + +#//forEach + 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); } + +#//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); //FIXUP no conversion. OK in .cpp { os<< r.print(orgQhull::UsingQhullLib::NOqhRunId); return os; } +std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge::PrintRidge &pr); + +#endif // QHULLRIDGE_H diff --git a/cpp/QhullSet.cpp b/cpp/QhullSet.cpp new file mode 100644 index 0000000..7ea431b --- /dev/null +++ b/cpp/QhullSet.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullSet.cpp#15 $$Change: 1027 $ +** $DateTime: 2009/07/03 21:11:23 $$Author: bbarber $ +** +****************************************************************************/ + +#//! QhullSet -- Qhull's facet structure, facetT, 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 int *sizep; + + if (!set) + return(0); + sizep= SETsizeaddr_(set); + if ((size= *sizep)) { + size--; + if (size > set->maxsize) { + throw QhullError(10032, "QhullSet internal error: current set size %d is greater than maximum size %d\n", + size, set->maxsize); + // FIXUP -- qh_setprint(qhmem.ferr, "set: ", set); + } + }else + size= set->maxsize; + return size; +} + + +}//namespace orgQhull + diff --git a/cpp/QhullSet.h b/cpp/QhullSet.h new file mode 100644 index 0000000..c9e2f8e --- /dev/null +++ b/cpp/QhullSet.h @@ -0,0 +1,346 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullSet.h#29 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QhullSet_H +#define QhullSet_H + +#ifndef QHULL_NO_STL +#include <vector> +#endif + +#ifdef QHULL_USES_QT + #include <QtCore/QList> +#endif + +#include "QhullError.h" + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//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 { +#//Class objects and functions +private: + static setT s_empty_set; //! Workaround for no setT allocator. Used if setT* is NULL + +public: + static int count(const setT *set); + //s may be null + static bool isEmpty(const setT *s) { return SETempty_(s); } + +#//Fields -- +private: + setT *qh_set; +public: + +#//Constructors + //! Copy constructor copies the pointer but not the set. Needed for return by value. + QhullSetBase(const QhullSetBase &o) : qh_set(o.qh_set) {} + explicit QhullSetBase(setT *s) : qh_set(s ? s : &s_empty_set) {} + +private: + //!disabled since memory allocation for QhullSet not defined + QhullSetBase() {} + //!disabled since qs= qs2 is ambiguous (pointer vs. contents) + QhullSetBase &operator=(const QhullSetBase &); +public: + +#//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; } + +#//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(); } + +#//Element +protected: + void **beginPointer() const { return &qh_set->e[0].p; } + void **elementPointer(int index) const { QHULL_ASSERT(index>=0 && index<qh_set->maxsize); return &SETelem_(qh_set, index); } + //! Always points to 0 + void **endPointer() const { int *i=SETsizeaddr_(qh_set); return (*i ? &qh_set->e[(*i)-1].p : reinterpret_cast<void **>(i)); } +};//QhullSetBase + + +//! set of pointers to baseT, T.getBaseT() +template <typename T> +class QhullSet : public QhullSetBase { + +public: +#//Types + typedef T *iterator; + typedef const T *const_iterator; + typedef typename QhullSet<T>::iterator Iterator; + typedef typename QhullSet<T>::const_iterator ConstIterator; + +#//Fields -- see QhullSetBase + +#//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: + +#//Conversion + +#ifndef QHULL_NO_STL + std::vector<T> toStdVector() const; +#endif +#ifdef QHULL_USES_QT + QList<T> toQList() const; +#endif + +#//Read-only -- see QhullSetBase for count(), empty(), isEmpty(), size() + using QhullSetBase::count; + // 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); } + +#//Element access + const T &at(int index) const { return operator[](index); } + 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 index) { T *n= reinterpret_cast<T *>(elementPointer(index)); QHULL_ASSERT(index>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; } + const T &operator[](int index) const { const T *n= reinterpret_cast<const T *>(elementPointer(index)); QHULL_ASSERT(index>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; } + T &second() { return operator[](1); } + const T &second() const { return operator[](1); } + T value(int index) const; + T value(int index, const T &defaultValue) const; + +#//Read-write -- Not available, no setT constructor + +#//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()); } + +#//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 { +#//Fields + typedef typename QhullSet<T>::const_iterator const_iterator; + const_iterator i; + const_iterator begin_i; + const_iterator end_i; + +public: +#//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; } + +#//ReadOnly + int countRemaining() { return (int)(end_i-begin_i); } // WARN64 + +#//Search + bool findNext(const T &t); + bool findPrevious(const T &t); + +#//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 + +#//== Definitions ========================================= + +#//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 + +#//Element + +template <typename T> +T QhullSet<T>:: +value(int index) const +{ + // Avoid call to qh_setsize() and assert in elementPointer() + const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), index)); + return (index>=0 && n<end()) ? *n : T(); +}//value + +template <typename T> +T QhullSet<T>:: +value(int index, const T &defaultValue) const +{ + // Avoid call to qh_setsize() and assert in elementPointer() + const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), index)); + return (index>=0 && n<end()) ? *n : defaultValue; +}//value + +#//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 + +#//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 + + +#//== Global namespace ========================================= + +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<< + +//FIXUP add runId to set.operator<< + +#endif // QhullSet_H diff --git a/cpp/QhullSets.h b/cpp/QhullSets.h new file mode 100644 index 0000000..dce0253 --- /dev/null +++ b/cpp/QhullSets.h @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullSets.h#4 $$Change: 1048 $ +** $DateTime: 2009/09/24 21:34:06 $$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/cpp/QhullStat.cpp b/cpp/QhullStat.cpp new file mode 100644 index 0000000..11dcd2c --- /dev/null +++ b/cpp/QhullStat.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullStat.cpp#5 $$Change: 1045 $ +** $DateTime: 2009/08/22 21:30:33 $$Author: bbarber $ +** +****************************************************************************/ + +#//! QhullStat -- Qhull's global data structure, statT, as a C++ class + + +#include <iostream> +#include <sstream> + +#include "QhullError.h" +#include "QhullStat.h" + +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/cpp/QhullStat.h b/cpp/QhullStat.h new file mode 100644 index 0000000..9a0471b --- /dev/null +++ b/cpp/QhullStat.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullStat.h#7 $$Change: 1053 $ +** $DateTime: 2009/10/02 22:00:28 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLSTAT_H +#define QHULLSTAT_H + +#include <string> +#include <vector> + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//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 { + +public: +#//class methods + static void clearStatistics(); + +#//Constants + +#//Fields (empty) -- POD type equivalent to qhstatT. No data or virtual members + +public: +#//constructor, assignment, destructor, invariant + QhullStat(); + ~QhullStat(); + +private: + //!disable copy constructor and assignment + QhullStat(const QhullStat &); + QhullStat &operator=(const QhullStat &); + +public: +#//Access +};//class QhullStat + +}//namespace orgQhull + +#endif // QHULLSTAT_H diff --git a/cpp/QhullVertex.cpp b/cpp/QhullVertex.cpp new file mode 100644 index 0000000..f30552f --- /dev/null +++ b/cpp/QhullVertex.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullVertex.cpp#18 $$Change: 1049 $ +** $DateTime: 2009/09/27 09:56:18 $$Author: bbarber $ +** +****************************************************************************/ + +#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class + +#include "UsingQhullLib.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= {}; + +#//ForEach +QhullFacetSet QhullVertex:: +neighborFacets() const +{ + if(!qh_vertex->neighbors){ + throw QhullError(10034, "Qhull error: neighbors of vertex %d not defined. Need to call defineVertexNeighbors().", 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::UsingQhullLib; + +//! 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 %5.2g + } + if(v.getVertexT()->deleted){ + os<< " deleted"; + } + if(v.getVertexT()->delridge){ + os<< " ridgedeleted"; + } + os<< endl; + 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/cpp/QhullVertex.h b/cpp/QhullVertex.h new file mode 100644 index 0000000..d5f1fbc --- /dev/null +++ b/cpp/QhullVertex.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullVertex.h#20 $$Change: 1057 $ +** $DateTime: 2009/10/22 20:38:42 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLVERTEX_H +#define QHULLVERTEX_H + +#include <ostream> + +#include "UsingQhullLib.h" +#include "QhullPoint.h" +#include "QhullLinkedList.h" +#include "QhullSet.h" + +extern "C" { + #include "../src/qhull_a.h" +}; + +namespace orgQhull { + +#//ClassRef + class QhullFacetSet; + +#//Types + //! QhullVertex -- Qhull's vertex structure, vertexT [qhulllib.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 { + +#//Fields + vertexT *qh_vertex; + +#//Class objects + static vertexT s_empty_vertex; // needed for shallow copy + +public: +#//Constants + +#//Constructors + QhullVertex() : qh_vertex(&s_empty_vertex) {} + //! Shallow copy + QhullVertex(const QhullVertex &o) : qh_vertex(o.qh_vertex) {} + QhullVertex &operator=(const QhullVertex &o) { qh_vertex= o.qh_vertex; return *this; } + ~QhullVertex() {} + +#//Conversion + //Implicit conversion from vertexT + QhullVertex(vertexT *v) : qh_vertex(v ? v : &s_empty_vertex) {} + vertexT *getVertexT() const { return qh_vertex; } + +#//QhullSet<QhullVertex> + vertexT *getBaseT() const { return getVertexT(); } + +#//getSet + int dimension() const { return (qh_vertex->dim || !isDefined()) ? qh_vertex->dim : UsingQhullLib::globalVertexDimension(); } + int id() const { return qh_vertex->id; } + bool isDefined() const { return qh_vertex != &s_empty_vertex; } + 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; } + +#//ForEach + //See also QhullVertexList + QhullFacetSet neighborFacets() const; + +#//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 + +#//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::UsingQhullLib::NOqhRunId); return os; } + +#endif // QHULLVERTEX_H diff --git a/cpp/QhullVertexSet.cpp b/cpp/QhullVertexSet.cpp new file mode 100644 index 0000000..b9e8ed8 --- /dev/null +++ b/cpp/QhullVertexSet.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullVertexSet.cpp#4 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$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) +{ + UsingQhullLib 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){ + UsingQhullLib 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::UsingQhullLib; + +//! Print Vertex identifiers to stream. Space prefix. From qh_printVertexheader [io.c] +ostream & +operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr) +{ + if(pr.message && *pr.message){ + os << pr.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==UsingQhullLib::NOqhRunId, no access to qh [needed for QhullPoint] +ostream & +operator<<(ostream &os, const QhullVertexSet::PrintVertexSet &pr){ + + os<< pr.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/cpp/QhullVertexSet.h b/cpp/QhullVertexSet.h new file mode 100644 index 0000000..0d7f0c0 --- /dev/null +++ b/cpp/QhullVertexSet.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/QhullVertexSet.h#3 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHULLVERTEXSET_H +#define QHULLVERTEXSET_H + +#include <ostream> + +#include "QhullSet.h" + +namespace orgQhull { + +#//ClassRef + class QhullVertex; + +#//Types + //! QhullVertexSet -- a set of Qhull Vertices, as a C++ class. + //! See Qhull + class QhullVertexSet; + typedef QhullSetIterator<QhullVertex> + QhullVertexSetIterator; + +class QhullVertexSet : public QhullSet<QhullVertex> { + +#//Fields +private: + Qhull *qhsettemp_qhull; //! For sets allocated with qh_settemp() + bool qhsettemp_defined; //! Set was allocated with q_memalloc() + +#//Constructor +public: + //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: + +#//Constructor, destructor + void freeQhSetTemp(); + +#//IO + struct PrintVertexSet{ + const QhullVertexSet *Vertex_set; + const char *message; + int run_id; + PrintVertexSet(int qhRunId, const char *message, const QhullVertexSet *s) : Vertex_set(s), 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 *message; + PrintIdentifiers(const char *message, const QhullVertexSet *s) : Vertex_set(s), message(message) {} + };//PrintIdentifiers + PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); } + +};//class QhullVertexSet + +}//namespace orgQhull + +#//== Global namespace ========================================= + +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::UsingQhullLib::NOqhRunId, ""); return os; } + +#endif // QHULLVERTEXSET_H diff --git a/cpp/RboxPoints.cpp b/cpp/RboxPoints.cpp new file mode 100644 index 0000000..5782e22 --- /dev/null +++ b/cpp/RboxPoints.cpp @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/RboxPoints.cpp#27 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> + +#include "QhullError.h" +#include "RboxPoints.h" + +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() +{ + 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() // FIXUP call destructor for PointCoordinates? +{} + +#//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. + 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; + + 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/cpp/RboxPoints.h b/cpp/RboxPoints.h new file mode 100644 index 0000000..b8aabb7 --- /dev/null +++ b/cpp/RboxPoints.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/RboxPoints.h#23 $$Change: 1095 $ +** $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef RBOXPOINTS_H +#define RBOXPOINTS_H + +#include <istream> +#include <ostream> +#include <sstream> +#include <stdarg.h> +#include <string> +#include <vector> + +#include "PointCoordinates.h" +#include "QhullPoint.h" + +extern "C" { +#include "../src/qhulllib.h" +}; + +namespace orgQhull { + +#//Types + //! RboxPoints -- generate random PointCoordinates for Qhull + class RboxPoints; + + class RboxPoints : public PointCoordinates { + +private: +#//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: +#//Construct + RboxPoints(); + explicit RboxPoints(const char *rboxCommand); + RboxPoints(const RboxPoints &other); + RboxPoints &operator=(const RboxPoints &other); + ~RboxPoints(); + +public: +#//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; } + +#//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/cpp/UsingQhullLib.cpp b/cpp/UsingQhullLib.cpp new file mode 100644 index 0000000..5d3dd97 --- /dev/null +++ b/cpp/UsingQhullLib.cpp @@ -0,0 +1,372 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/UsingQhullLib.cpp#16 $$Change: 1087 $ +** $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ +** +****************************************************************************/ + +#//! UsingQhullLib -- Set up qhull C code from C++ + +#include "Qhull.h" +#include "UsingQhullLib.h" +#include "QhullError.h" +#include "QhullQh.h" + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//Class objects + +const double UsingQhullLib:: +DEFAULTdistanceEpsilon= 1e-15*FACTORepsilon; //! ~DISTround*FACTORepsilon for unit cube + +const double UsingQhullLib:: +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 UsingQhullLib:: +s_angle_epsilon= 0; + +double UsingQhullLib:: +s_distance_epsilon= 0; + +//! For QhullPoint.id() w/o qhRunId. Initialized by Qhull +const coordT *UsingQhullLib:: +s_points_begin= 0; +const coordT *UsingQhullLib:: +s_points_end= 0; +int UsingQhullLib:: +s_points_dimension= 0; + +int UsingQhullLib:: +s_vertex_dimension= 0; // FIXUP: required if dimension>15 + +bool UsingQhullLib:: +s_has_points= false; + +bool UsingQhullLib:: +s_has_angle_epsilon= false; + +bool UsingQhullLib:: +s_has_vertex_dimension= false; + +bool UsingQhullLib:: +s_has_distance_epsilon= false; + +bool UsingQhullLib:: +s_using_qhulllib= false; + +#//Constructors + +//! Grabs global state (qh_qh, qh_qhstat, qhmem.tempstack) +//! Follow immediately with setjmp(qh errexit), otherwise errors in qhulllib are not caught properly +//! See qh_restore_qhull [global.c] +UsingQhullLib:: +UsingQhullLib(Qhull *q) +: my_qhull(q) +, qh_exitcode(0) +{ + checkUsingQhullLib(); + 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 UsingQhullLib() are the same +#if qh_QHpointer + if(qh_qh){ + qh old_qhstat= qh_qhstat; + qh old_tempstack= static_cast<setT *>(qhmem.tempstack); + } + qh_qh= qhullqh; + qh_qhstat= static_cast<qhstatT *>(qhullqh->old_qhstat); + qhmem.tempstack= qhullqh->old_tempstack; + qhullqh->old_qhstat= 0; + qhullqh->old_tempstack= 0; +#else + #error FIXUP 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 +}//UsingQhullLib qhull + +//! Same as UsingQhullLib but does not throw exceptions +//! !defined() on failure. For use in destructors +UsingQhullLib:: +UsingQhullLib(Qhull *q, int noThrow) +: my_qhull(0) // Fail by default +, qh_exitcode(0) +{ + QhullQh *qhullqh= q->qhullQh(); + if(s_using_qhulllib){ + QhullError e(10050, "Qhull error: UsingQhullLib 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 UsingQhullLib() are the same +#if qh_QHpointer + if(qh_qh){ + qh old_qhstat= qh_qhstat; + qh old_tempstack= static_cast<setT *>(qhmem.tempstack); + } + qh_qh= qhullqh; + qh_qhstat= static_cast<qhstatT *>(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 + } +}//UsingQhullLib qhull noThrow + +//! Reuses current global state (qh_qh) from prior UsingQhull +//! Errors if runId is not the same +UsingQhullLib:: +UsingQhullLib(int qhRunId) +: my_qhull(0) +, qh_exitcode(0) +{ + checkUsingQhullLib(); +#if qh_QHpointer + if(!qh_qh || !qh_qhstat){ + throw QhullError(10024, "Qhull error: UsingQhullLIb 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: UsingQhullLib not active(s_qhull_output undefined). Invoke UsingQhullLIb 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 +}//UsingQhullLib runId + +//Leaves QHullLib active for runId access +UsingQhullLib:: +~UsingQhullLib() +{ + QhullError e= checkRunId(); + if(e.defined()){ + e.logError(); + }else{ +#if qh_QHpointer + if(qh_qh){ + qh NOerrexit= true; + } +#else + qh NOerrexit= true; +#endif + } + s_using_qhulllib= false; +}//~UsingQhullLib + +#//Class methods + +void UsingQhullLib:: +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 + +double UsingQhullLib:: +currentAngleEpsilon() +{ + if(s_qhull_output && s_qhull_output->defined()){ + return s_qhull_output->qhullQh()->ANGLEround*FACTORepsilon; + }else if(s_has_angle_epsilon){ + return s_angle_epsilon; + } + return UsingQhullLib::DEFAULTangleEpsilon; +}//currentAngleEpsilon + +double UsingQhullLib:: +currentDistanceEpsilon() +{ + if(s_qhull_output && s_qhull_output->defined()){ + return s_qhull_output->qhullQh()->DISTround*FACTORepsilon; + }else if(s_has_distance_epsilon){ + return s_distance_epsilon; + } + return UsingQhullLib::DEFAULTdistanceEpsilon; +}//currentDistanceEpsilon + +const coordT *UsingQhullLib:: +currentPoints(int *dimension, const coordT **pointsEnd) +{ + if(s_qhull_output && s_qhull_output->defined()){ + *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()"); +}//globalPoints + +Qhull &UsingQhullLib:: +currentQhull() +{ + if(!s_qhull_output){ + throw QhullError(10055, "Qhull error: currentQhull not defined. Run qhull first."); + } + return *s_qhull_output; +}//currentQhull + +int UsingQhullLib:: +currentVertexDimension() +{ + if(s_qhull_output && s_qhull_output->defined()){ + 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 *UsingQhullLib:: +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 UsingQhullLib:: +hasPoints() +{ + return s_has_points || (s_qhull_output && s_qhull_output->defined()); +} + +bool UsingQhullLib:: +hasVertexDimension() +{ + return s_has_vertex_dimension || (s_qhull_output && s_qhull_output->defined()); +} + +void UsingQhullLib:: +setGlobals() +{ + if(s_qhull_output && s_qhull_output->defined()){ + 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 UsingQhullLib:: +unsetGlobals() +{ + s_has_angle_epsilon= false; + s_has_distance_epsilon= false; + s_has_points= false; + s_has_vertex_dimension= false; +}//unsetGlobals + +#// Methods + +void UsingQhullLib:: +maybeThrowQhullMessage(int exitCode) const +{ + my_qhull->maybeThrowQhullMessage(exitCode); + QhullError e= checkRunId(); // Check for qhRunId after qhulllib returns. For convenience, ought to be at end of qhulllib try block + if(e.defined()){ + throw e; + } +}//maybeThrowQhullMessage + + +void UsingQhullLib:: +maybeThrowQhullMessage(int exitCode, int noThrow) const +{ + my_qhull->maybeThrowQhullMessage(exitCode, noThrow); + QhullError e= checkRunId(); // Check for qhRunId after qhulllib returns. For convenience, ought to be at end of qhulllib try block + if(e.defined()){ + e.logError(); + } +}//maybeThrowQhullMessage + + +#//Helpers + +//! Return QhullError for maybeThrowFromDestructor() +QhullError UsingQhullLib:: +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 UsingQhullLib. Otherwise allocated a C++ object missed by qh_errexit +void UsingQhullLib:: +checkUsingQhullLib() const +{ + if(s_using_qhulllib){ + if(s_qhull_output){ + throw QhullError(10049, "Qhull error: UsingQhullLib already in use by QhullQh.runId %d", s_qhull_output->qhull_run_id); + }else{ + throw QhullError(10050, "Qhull error: UsingQhullLib already in use. No s_qhull_output"); + } + } + s_using_qhulllib= true; +}//checkUsingQhullLib + +}//namespace orgQhull + diff --git a/cpp/UsingQhullLib.h b/cpp/UsingQhullLib.h new file mode 100644 index 0000000..03a79c5 --- /dev/null +++ b/cpp/UsingQhullLib.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/UsingQhullLib.h#16 $$Change: 1061 $ +** $DateTime: 2009/11/07 17:14:02 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef USINGQHULLLIB_H +#define USINGQHULLLIB_H + +#include "QhullError.h" + +extern "C" { +#include "../src/qhulllib.h" +}; + +namespace orgQhull { + +#//Types + //! UsingQhullLib -- Interface into qhulllib and its 'qh' and 'qhstat' macros + //! Always use with setjmp() for qhulllib error handling. + +/******************************* + +UsingQhullLIb 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 UsingQhullLib, but can only have one +setjmp at a time? Can embedded another Using as long as save/restore +longjmp on exit. +*/ + class UsingQhullLib; + + // Defined elsewhere + class Qhull; + +#// Global variables +extern Qhull *s_qhull_output; //! Provide qh_fprintf (Qhull.cpp) access to Qhull + +class UsingQhullLib { + +private: +#//Fields + Qhull *my_qhull; + int qh_exitcode; + +#//Class globals + //! Global flags + static bool s_using_qhulllib; //! True if UsingQhullLib 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) + +#//Class constants +public: + 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 + +#//Constructors + UsingQhullLib(Qhull *p); + UsingQhullLib(Qhull *p, int noThrow); + UsingQhullLib(int qhRunId); + ~UsingQhullLib(); + +public: +#//Class members + static void checkQhullMemoryEmpty(); + static double currentAngleEpsilon(); + static double currentDistanceEpsilon(); + static const coordT *currentPoints(int *dimension, const coordT **pointsEnd); + static Qhull ¤tQhull(); + 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(); + +#//Methods + bool defined() const { return my_qhull!=0; } + void maybeThrowQhullMessage(int exitCode) const; + void maybeThrowQhullMessage(int exitCode, int noThrow) const; + +#//Helpers +private: + QhullError checkRunId() const; + void checkUsingQhullLib() const; + +/*********************************** +You may use global variables in 'qh' after declaring UsingQhullLib. For example + + UsingQhullLib q(qhRunId); + // NOerrors -- no calls that throw qhulllib errors + cout << "Delaunay Mode: " << qh DELAUNAY; + +To trap errors from qhulllib, UsingQhullLib must be followed by + +UsingQhullLib q(qhRunId); +int exitCode = setjmp(qh errexit); +if(!exitCode){ // no object creation -- destructors skipped on longjmp() + calls to qhulllib +} +q.maybeThrowQhullMessage(exitCode); + +The call to setjmp() can not be moved to a method. The stack must be preserved for error exits from qhulllib. + +*/ + +};//UsingQhullLib + +}//namespace orgQhull + +#endif // USINGQHULLLIB_H diff --git a/cpp/functionObjects.h b/cpp/functionObjects.h new file mode 100644 index 0000000..9cf317e --- /dev/null +++ b/cpp/functionObjects.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/functionObjects.h#2 $$Change: 995 $ +** $DateTime: 2009/02/14 14:02:01 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef QHFUNCTIONOBJECTS_H +#define QHFUNCTIONOBJECTS_H + +namespace orgQhull { +#//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; + +#//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 += abs(v); } + inline operator double() { return sum; } +};//AbsoluteSumOf + +//! Sum of the elements in a container +class SumOf +{ +private: + double sum; +public: + inline SumOf() : sum(0.0) {} + inline void operator()(double v) { sum += v; } + inline operator double() { return sum; } +};//SumOf + + +//! Sum of squares of the elements in a container +class SumSquaresOf +{ +private: + double sum; +public: + inline SumSquaresOf() : sum(0.0) {} + inline void operator()(double v) { sum += v*v; } + inline operator double() { return sum; } +};//SumSquaresOf + + +}//orgQhull + + +#endif //QHFUNCTIONOBJECTS_H + diff --git a/src/qhull_interface.cpp b/cpp/qhull_interface.cpp similarity index 92% rename from src/qhull_interface.cpp rename to cpp/qhull_interface.cpp index 6ecc640..f460e57 100644 --- a/src/qhull_interface.cpp +++ b/cpp/qhull_interface.cpp @@ -29,7 +29,7 @@ extern "C" #endif #include <stdio.h> #include <stdlib.h> -#include <qhull/qhull.h> +#include <qhull/qhulllib.h> #include <qhull/mem.h> #include <qhull/qset.h> #include <qhull/geom.h> @@ -63,7 +63,7 @@ void compute_convex_hull(void) int curlong, totlong; /* memory remaining after qh_memfreeshort */ /* initialize dim, numpoints, points[], ismalloc here */ - exitcode= qh_new_qhull (dim, numpoints, points, ismalloc, + exitcode= qh_new_qhull(dim, numpoints, points, ismalloc, flags, outfile, errfile); if (!exitcode) { /* if no error */ /* 'qh facet_list' contains the convex hull */ @@ -72,9 +72,9 @@ void compute_convex_hull(void) } } qh_freeqhull(!qh_ALL); - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) - fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", + fprintf(errfile, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); }; @@ -91,6 +91,6 @@ void main() cout << "Press any key..." << endl; - while(!_kbhit()); + while (!_kbhit()); }; diff --git a/cpp/qhulltest/Coordinates_test.cpp b/cpp/qhulltest/Coordinates_test.cpp new file mode 100644 index 0000000..d589363 --- /dev/null +++ b/cpp/qhulltest/Coordinates_test.cpp @@ -0,0 +1,547 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/Coordinates_test.cpp#11 $$Change: 1095 $ +** $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "Qhull.h" +#include "QhullError.h" +#include "Coordinates.h" +#include "RboxPoints.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); //FIXUP move to Coordinates_test + 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()); +}//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 + +#//Conversions + +//FIXUP -- Move conditional, Coordinates code to Coordinates.cpp + +#ifdef QHULL_USES_QT +QList<coordT> Coordinates:: +toQList() const +{ + CoordinatesIterator i(*this); + QList<coordT> cs; + while(i.hasNext()){ + cs.append(i.next()); + } + return cs; +}//toQList +#endif //QHULL_USES_QT + + +}//orgQhull + +#include "moc/Coordinates_test.moc" diff --git a/cpp/qhulltest/PointCoordinates_test.cpp b/cpp/qhulltest/PointCoordinates_test.cpp new file mode 100644 index 0000000..2856260 --- /dev/null +++ b/cpp/qhulltest/PointCoordinates_test.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/PointCoordinates_test.cpp#7 $$Change: 1094 $ +** $DateTime: 2009/11/24 20:04:16 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "Qhull.h" +#include "QhullError.h" +#include "PointCoordinates.h" +#include "RboxPoints.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_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(); // g++ error, begin() returns iterator + QhullPoints::ConstIterator i2= pc2.begin(); + const QhullPoint p0= pc2[0]; + QCOMPARE(*i2, p0); + QCOMPARE((*i2)[0], 0.0); + QhullPoints::ConstIterator i3= pc2.constBegin(); + 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 p, pc){ //Qt only + QVERIFY(p[0]>=0.0); + QVERIFY(p[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_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 + +#//Conversions + +//FIXUP -- Move conditional, PointCoordinates code to PointCoordinates.cpp + +}//orgQhull + +#include "moc/PointCoordinates_test.moc" diff --git a/cpp/qhulltest/Point_test.cpp b/cpp/qhulltest/Point_test.cpp new file mode 100644 index 0000000..648afbd --- /dev/null +++ b/cpp/qhulltest/Point_test.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (p) 2009-2009 p. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/Point_test.cpp#10 $$Change: 1057 $ +** $DateTime: 2009/10/22 20:38:42 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +using std::cout; +using std::endl; +#include "../road/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/cpp/qhulltest/QhullFacetList_test.cpp b/cpp/qhulltest/QhullFacetList_test.cpp new file mode 100644 index 0000000..4b9dc17 --- /dev/null +++ b/cpp/qhulltest/QhullFacetList_test.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullFacetList_test.cpp#10 $$Change: 1049 $ +** $DateTime: 2009/09/27 09:56:18 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "QhullFacetList.h" +#include "QhullVertexSet.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() +{ + UsingQhullLib::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 + +//FIXUP -- Move conditional, QhullFacetSet code to QhullFacetSet.cpp +#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 + +#ifdef QHULL_USES_QT +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 +#endif //QHULL_USES_QT + +#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 + +#ifdef QHULL_USES_QT +//! 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 +#endif //QHULL_USES_QT +}//orgQhull + +#include "moc/QhullFacetList_test.moc" diff --git a/cpp/qhulltest/QhullFacetSet_test.cpp b/cpp/qhulltest/QhullFacetSet_test.cpp new file mode 100644 index 0000000..a402a85 --- /dev/null +++ b/cpp/qhulltest/QhullFacetSet_test.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullFacetSet_test.cpp#7 $$Change: 1047 $ +** $DateTime: 2009/09/12 21:08:23 $$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/cpp/qhulltest/QhullFacet_test.cpp b/cpp/qhulltest/QhullFacet_test.cpp new file mode 100644 index 0000000..ad8c723 --- /dev/null +++ b/cpp/qhulltest/QhullFacet_test.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullFacet_test.cpp#25 $$Change: 1061 $ +** $DateTime: 2009/11/07 17:14:02 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" + +#include "QhullFacet.h" + +#include "Coordinates.h" +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacetList.h" +#include "QhullFacetSet.h" +#include "QhullPointSet.h" +#include "QhullRidge.h" +#include "RboxPoints.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() +{ + UsingQhullLib::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 i= 0; i<3; i++){ + QVERIFY(ho[i]==hi[i]); + QVERIFY(ho[i]==h[i]); + } + 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 i= 0; i<3; i++){ + QVERIFY(center4[i]==center3[i]); + } + Qhull q3(rcube,"v Qz QR0"); // Voronoi diagram of a cube (one vertex) + + foreach(QhullFacet f, q3.facetList()){ //Qt only + if(f.isGood()){ + QhullPoint p= f.voronoiVertex(q3.runId()); + cout << p.print(q3.runId(), "Voronoi vertex: ") + << " DistanceEpsilon " << UsingQhullLib::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"); // 300 points on surface of cube + { + 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; + } + 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/cpp/qhulltest/QhullHyperplane_test.cpp b/cpp/qhulltest/QhullHyperplane_test.cpp new file mode 100644 index 0000000..984b5ee --- /dev/null +++ b/cpp/qhulltest/QhullHyperplane_test.cpp @@ -0,0 +1,442 @@ +/**************************************************************************** +** +** Copyright (C) 2009-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullHyperplane_test.cpp#5 $$Change: 1057 $ +** $DateTime: 2009/10/22 20:38:42 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include <vector> + +#include "../road/RoadTest.h" + +#include <numeric> // After RoadTest.h for precompiled headers + +#include "QhullHyperplane.h" + +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "QhullFacetList.h" +#include "RboxPoints.h" + +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() +{ + UsingQhullLib::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 i= h.end()-h.begin(); + QCOMPARE(i, 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 + + +//FIXUP -- Move conditional, QhullHyperplane code to QhullHyperplane.cpp +#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 + +#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 + +}//orgQhull + +#include "moc/QhullHyperplane_test.moc" diff --git a/cpp/qhulltest/QhullLinkedList_test.cpp b/cpp/qhulltest/QhullLinkedList_test.cpp new file mode 100644 index 0000000..d5fbae2 --- /dev/null +++ b/cpp/qhulltest/QhullLinkedList_test.cpp @@ -0,0 +1,330 @@ +/**************************************************************************** +** +** Copyright (f) 2009-2009 f. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullLinkedList_test.cpp#9 $$Change: 1047 $ +** $DateTime: 2009/09/12 21:08:23 $$Author: bbarber $ +** +****************************************************************************/ + +#include <QtCore/QList> +#include "../road/RoadTest.h"// FIXUP First for QHULL_USES_QT + +#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() +{ + UsingQhullLib::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); + // FIXUP -- iterator or vertex for vertexList? + 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; // private (compiler error) + 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/cpp/qhulltest/QhullPointSet_test.cpp b/cpp/qhulltest/QhullPointSet_test.cpp new file mode 100644 index 0000000..f905399 --- /dev/null +++ b/cpp/qhulltest/QhullPointSet_test.cpp @@ -0,0 +1,398 @@ +/**************************************************************************** +** +** Copyright (p) 2009-2009 p. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullPointSet_test.cpp#3 $$Change: 1047 $ +** $DateTime: 2009/09/12 21:08:23 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "QhullPointSet.h" + +#include "Qhull.h" +#include "QhullFacet.h" +#include "QhullFacetList.h" +#include "QhullPoint.h" +#include "RboxPoints.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() +{ + UsingQhullLib::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 p, ps){ // Qt only + QCOMPARE(p.dimension(), 3); + QCOMPARE(p, *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 + +//FIXUP -- Move conditional, QhullPointSet code to QhullPointSet.cpp +#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 + +#ifdef QHULL_USES_QT +QList<QhullPoint> QhullPointSet:: +toQList() const +{ + QhullPointSetIterator i(*this); + QList<QhullPoint> vs; + while(i.hasNext()){ + vs.append(i.next()); + } + return vs; +}//toQList +#endif //QHULL_USES_QT + + +}//orgQhull + +#include "moc/QhullPointSet_test.moc" diff --git a/cpp/qhulltest/QhullPoint_test.cpp b/cpp/qhulltest/QhullPoint_test.cpp new file mode 100644 index 0000000..9548fd6 --- /dev/null +++ b/cpp/qhulltest/QhullPoint_test.cpp @@ -0,0 +1,423 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullPoint_test.cpp#9 $$Change: 1058 $ +** $DateTime: 2009/10/29 22:11:06 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include <numeric> +#include "../road/RoadTest.h" + +#include "QhullPoint.h" + +#include "Coordinates.h" +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "QhullPoint.h" +#include "RboxPoints.h" + +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() +{ + UsingQhullLib::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 index= (p3.coordinates()-p2.coordinates())/p2.dimension(); + QVERIFY(index>-8 && index<8); + p2.advancePoint(index); + QVERIFY(p2==p3); + p2.advancePoint(-index); + 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 + +//FIXUP -- Move conditional, QhullPoint code to QhullPoint.cpp +#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 + +#ifdef QHULL_USES_QT +QList<coordT> QhullPoint:: +toQList() const +{ + QhullPointIterator i(*this); + QList<coordT> vs; + while(i.hasNext()){ + vs.append(i.next()); + } + return vs; +}//toQList +#endif //QHULL_USES_QT + +}//orgQhull + +#include "moc/QhullPoint_test.moc" diff --git a/cpp/qhulltest/QhullPoints_test.cpp b/cpp/qhulltest/QhullPoints_test.cpp new file mode 100644 index 0000000..d54bd1c --- /dev/null +++ b/cpp/qhulltest/QhullPoints_test.cpp @@ -0,0 +1,508 @@ +/**************************************************************************** +** +** Copyright (p) 2009-2009 p. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullPoints_test.cpp#11 $$Change: 1095 $ +** $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "QhullPoints.h" + +#include "Qhull.h" +#include "RboxPoints.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() +{ + UsingQhullLib::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 p, ps){ // Qt only + QCOMPARE(p.dimension(), 2); + QVERIFY(p[0]==0.0 || p[0]==2.0 || p[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); + 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 + +//FIXUP -- Move conditional, QhullPoints code to QhullPoints.cpp +#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 + +#ifdef QHULL_USES_QT +QList<QhullPoint> QhullPoints:: +toQList() const +{ + QhullPointsIterator i(*this); + QList<QhullPoint> vs; + while(i.hasNext()){ + vs.append(i.next()); + } + return vs; +}//toQList +#endif //QHULL_USES_QT + +}//orgQhull + +#include "moc/QhullPoints_test.moc" diff --git a/cpp/qhulltest/QhullRidge_test.cpp b/cpp/qhulltest/QhullRidge_test.cpp new file mode 100644 index 0000000..648b542 --- /dev/null +++ b/cpp/qhulltest/QhullRidge_test.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullRidge_test.cpp#6 $$Change: 1047 $ +** $DateTime: 2009/09/12 21:08:23 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" + +#include "QhullRidge.h" + +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "RboxPoints.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() +{ + UsingQhullLib::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; + 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/cpp/qhulltest/QhullSet_test.cpp b/cpp/qhulltest/QhullSet_test.cpp new file mode 100644 index 0000000..126b115 --- /dev/null +++ b/cpp/qhulltest/QhullSet_test.cpp @@ -0,0 +1,400 @@ +/**************************************************************************** +** +** Copyright (f) 2009-2009 f. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullSet_test.cpp#14 $$Change: 1047 $ +** $DateTime: 2009/09/12 21:08:23 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include <QtCore/QList> +#include "../road/RoadTest.h" // QT_VERSION + +#include "Qhull.h" +#include "QhullFacetSet.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() +{ + UsingQhullLib::checkQhullMemoryEmpty(); + RoadTest::cleanup(); +} + +void QhullSet_test:: +t_qhullsetbase() +{ + RboxPoints rcube("c"); + { + Qhull q(rcube,"Qt 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); + 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())); + + QCOMPARE(q.facetCount(), 12); + QhullFacet f = q.beginFacet(); + QhullFacetSet fs2 = f.neighborFacets(); + QCOMPARE(fs2.count(), 3); + QCOMPARE(fs2.size(), 3u); + 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; // private (compiler error) + 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,"Qt QR0"); // triangulation of rotated unit cube + QCOMPARE(q.facetCount(), 12); + QhullFacet f = q.beginFacet(); + QhullFacetSet fs = f.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: " << fs2 << std::endl; + //FIXUP do not use QhullFacetSet to test set +}//t_io + +}//namespace orgQhull + +#include "moc/QhullSet_test.moc" diff --git a/cpp/qhulltest/QhullVertexSet_test.cpp b/cpp/qhulltest/QhullVertexSet_test.cpp new file mode 100644 index 0000000..a831426 --- /dev/null +++ b/cpp/qhulltest/QhullVertexSet_test.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullVertexSet_test.cpp#1 $$Change: 1048 $ +** $DateTime: 2009/09/24 21:34:06 $$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/cpp/qhulltest/QhullVertex_test.cpp b/cpp/qhulltest/QhullVertex_test.cpp new file mode 100644 index 0000000..4265a95 --- /dev/null +++ b/cpp/qhulltest/QhullVertex_test.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/QhullVertex_test.cpp#6 $$Change: 1049 $ +** $DateTime: 2009/09/27 09:56:18 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" + +#include "QhullVertex.h" + +#include "Coordinates.h" +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "QhullFacetSet.h" +#include "QhullVertexSet.h" +#include "RboxPoints.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() +{ + UsingQhullLib::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 i= p.id(q.runId()); + cout<< "Point " << i << ":\n" << p.print(q.runId()) << endl; + QVERIFY(i>=0 && i<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); + } +}//t_io + +}//orgQhull + +#include "moc/QhullVertex_test.moc" diff --git a/cpp/qhulltest/Qhull_test.cpp b/cpp/qhulltest/Qhull_test.cpp new file mode 100644 index 0000000..7d133bb --- /dev/null +++ b/cpp/qhulltest/Qhull_test.cpp @@ -0,0 +1,345 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/Qhull_test.cpp#30 $$Change: 1095 $ +** $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacetList.h" +#include "RboxPoints.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() +{ + UsingQhullLib::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(); + } + } + { + RboxPoints rbox("10000"); + Qhull q(rbox, "QR0"); // Random points in a randomly rotated cube. + QCOMPARE(q.dimension(),3); + QVERIFY(q.volume() < 1.0); + QVERIFY(q.volume() > 0.99); + } + { + double points[] = { + 0, 0, + 1, 0, + 1, 1 + }; + Qhull q("triangle", 2, 3, points, ""); + QCOMPARE(q.dimension(),2); + QCOMPARE(q.facetCount(),3); + QCOMPARE(q.vertexCount(),3); + QCOMPARE(q.dimension(),2); + QCOMPARE(q.area(), 2.0+sqrt(2.0)); // length of boundary + QCOMPARE(q.volume(), 0.5); // the 2-d area + } +}//t_construct + +void Qhull_test:: +t_attribute() +{ + RboxPoints rcube("c"); + { + double normals[] = { + 0, -1, -0.5, + -1, 0, -0.5, + 1, 0, -0.5, + 0, 1, -0.5 + }; + Qhull q; + 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; + QVERIFY(q.hasQhullMessage()); + QCOMPARE(QString::fromStdString(q.qhullMessage()), QString::fromStdString(s).remove(0, 7)); + QCOMPARE(QString::fromStdString(q.qhullMessage()).left(9), QString("qhull err")); + 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; + } + QVERIFY(q.hasQhullMessage()); + QCOMPARE(QString::fromStdString(q.qhullMessage()).left(17), QString("qhull: no message")); + QCOMPARE(q.qhullStatus(), 6029); + 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; + } + 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; + } + 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.defined()); + q.runQhull(rcube, "s"); + QVERIFY(q.defined()); + 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 -- UsingQhullLib [Qhull.cpp] + // runId -- UsingQhullLib [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 [qhulllib.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); + + 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(); //FIXUP disabled OK? + 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 errstatus) { + cout<< "FAIL! : Qhull called qh_exit(). Qhull's error handling not available.\n.. See the corresponding Qhull:qhull_message or setErrorStream().\n"; + exit(errstatus); +} +void qh_free(void *mem) { + free(mem); +} +void *qh_malloc(unsigned int 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/cpp/qhulltest/RboxPoints_test.cpp b/cpp/qhulltest/RboxPoints_test.cpp new file mode 100644 index 0000000..19b3bfa --- /dev/null +++ b/cpp/qhulltest/RboxPoints_test.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2006-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/RboxPoints_test.cpp#14 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "QhullError.h" +#include "RboxPoints.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::ConstIterator cci4= rp.beginCoordinates(4); + orgQhull::Coordinates::Iterator ci4= rp.beginCoordinates(4); + QCOMPARE(rp.endCoordinates()-cci4, 4*3); + QCOMPARE(rp.endCoordinates()-ci4, 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/cpp/qhulltest/UsingQhullLib_test.cpp b/cpp/qhulltest/UsingQhullLib_test.cpp new file mode 100644 index 0000000..ae42686 --- /dev/null +++ b/cpp/qhulltest/UsingQhullLib_test.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/UsingQhullLib_test.cpp#11 $$Change: 1091 $ +** $DateTime: 2009/11/23 22:13:59 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include "../road/RoadTest.h" // QT_VERSION + +#include "Qhull.h" +#include "QhullError.h" +#include "UsingQhullLib.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 UsingQhullLib_test : public RoadTest +{ + Q_OBJECT + +#//Test slots +private slots: + void cleanup(); + void t_classMembers(); + void t_globalPoints(); + void t_UsingQhullLib(); + void t_methods(); + void t_cleanuptestcase(); +};//UsingQhullLib_test + +void +add_UsingQhullLib_test() +{ + new UsingQhullLib_test(); +} + +//Executed after each testcase +void UsingQhullLib_test:: +cleanup() +{ + UsingQhullLib::checkQhullMemoryEmpty(); + RoadTest::cleanup(); +} + +void UsingQhullLib_test:: +t_classMembers() +{ + { + //checkQhullMemoryEmpty tested by cleanup() + QCOMPARE(UsingQhullLib::globalMachineEpsilon()+1.0, 1.0); + RboxPoints r10("10"); + Qhull q(r10,"v"); // voronoi diagram of 10 points + UsingQhullLib::unsetGlobalAngleEpsilon(); + UsingQhullLib::unsetGlobalDistanceEpsilon(); + cout << "MachineEpsilon " << UsingQhullLib::globalMachineEpsilon() + << " angleEpsilon " << UsingQhullLib::globalAngleEpsilon() + << " distanceEpsilon " << UsingQhullLib::globalDistanceEpsilon() + << endl; + QCOMPARE(UsingQhullLib::currentAngleEpsilon()+1.0, 1.0); + QVERIFY(UsingQhullLib::currentAngleEpsilon() > UsingQhullLib::globalMachineEpsilon()); + QCOMPARE(UsingQhullLib::currentDistanceEpsilon()+1.0, 1.0); + QVERIFY(UsingQhullLib::currentDistanceEpsilon() >= UsingQhullLib::currentAngleEpsilon()); + QCOMPARE(UsingQhullLib::currentQhull().runId(), q.runId()); + QCOMPARE(UsingQhullLib::globalAngleEpsilon()+1.0, UsingQhullLib::currentAngleEpsilon()+1.0); + QCOMPARE(UsingQhullLib::currentVertexDimension(), q.dimension()); + QCOMPARE(UsingQhullLib::globalDistanceEpsilon()+1.0, UsingQhullLib::currentDistanceEpsilon()+1.0); + UsingQhullLib::setGlobalAngleEpsilon(1.0); + UsingQhullLib::setGlobalDistanceEpsilon(1.0); + cout << " Global angleEpsilon " << UsingQhullLib::globalAngleEpsilon() + << " distanceEpsilon " << UsingQhullLib::globalDistanceEpsilon() + << endl; + QCOMPARE(UsingQhullLib::globalAngleEpsilon(), UsingQhullLib::globalDistanceEpsilon()); + QVERIFY(UsingQhullLib::currentAngleEpsilon() != UsingQhullLib::globalAngleEpsilon()); + UsingQhullLib::setGlobalVertexDimension(3); + QCOMPARE(UsingQhullLib::globalVertexDimension(), UsingQhullLib::currentVertexDimension()); + UsingQhullLib::setGlobalVertexDimension(2); + QCOMPARE(UsingQhullLib::globalVertexDimension(), 2); + QCOMPARE(UsingQhullLib::currentVertexDimension(), q.dimension()); + QVERIFY(UsingQhullLib::currentDistanceEpsilon() != UsingQhullLib::globalDistanceEpsilon()); + UsingQhullLib::unsetGlobalAngleEpsilon(); + UsingQhullLib::unsetGlobalVertexDimension(); + UsingQhullLib::unsetGlobalDistanceEpsilon(); + QCOMPARE(UsingQhullLib::currentAngleEpsilon()+1.0, UsingQhullLib::globalAngleEpsilon()+1.0); + QCOMPARE(UsingQhullLib::globalVertexDimension(), UsingQhullLib::currentVertexDimension()); + QCOMPARE(UsingQhullLib::currentDistanceEpsilon()+1.0, UsingQhullLib::globalDistanceEpsilon()+1.0); + UsingQhullLib::setGlobals(); + } + QCOMPARE(UsingQhullLib::globalAngleEpsilon()+1.0, 1.0); + QCOMPARE(UsingQhullLib::globalVertexDimension(), 4); // 'v'. VertexDimension is only used for QhullVertex where dim>15 + QCOMPARE(UsingQhullLib::globalDistanceEpsilon()+1.0, 1.0); + UsingQhullLib::unsetGlobals(); + try{ + cout<< UsingQhullLib::globalVertexDimension(); + QFAIL("Did not throw error for undefined dimension."); + }catch(const std::exception &e){ + cout<< "INFO Caught error -- " << e.what() << endl; + } +}//t_classMembers + +void UsingQhullLib_test:: +t_globalPoints() +{ + const coordT *r10PointsBegin; + { + RboxPoints r10("10"); + Qhull q(r10,"v"); // voronoi diagram of 10 points + UsingQhullLib::unsetGlobalPoints(); + int dimension; + const coordT *pointsEnd; + const coordT *pointsBegin= UsingQhullLib::globalPoints(&dimension, &pointsEnd); + cout << "pointsBegin " << pointsBegin + << " pointsEnd " << pointsEnd + << " dimension " << dimension + << endl; + int dimension2; + const coordT *pointsEnd2; + const coordT *pointsBegin2= UsingQhullLib::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 }; + UsingQhullLib::setGlobalPoints(2, c, c+3*2); + pointsBegin= UsingQhullLib::globalPoints(&dimension, &pointsEnd); + QCOMPARE(pointsBegin, c); + QCOMPARE(pointsEnd[-1], 6.0); + QCOMPARE(dimension, 2); + UsingQhullLib::unsetGlobalPoints(); + pointsBegin= UsingQhullLib::globalPoints(&dimension, &pointsEnd); + QCOMPARE(pointsBegin, pointsBegin2); + QCOMPARE(pointsEnd, pointsEnd2); + QCOMPARE(dimension, dimension2); + UsingQhullLib::setGlobals(); + r10PointsBegin= pointsBegin; + } + int dimension3; + const coordT *pointsEnd3; + const coordT *pointsBegin3= UsingQhullLib::currentPoints(&dimension3, &pointsEnd3); + QCOMPARE(pointsBegin3, r10PointsBegin); // Memory was freed + QCOMPARE(pointsEnd3, r10PointsBegin+10*4); + QCOMPARE(dimension3, 4); + UsingQhullLib::unsetGlobals(); + try{ + pointsBegin3= UsingQhullLib::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 UsingQhullLib_test:: +t_UsingQhullLib() +{ + { + Qhull q; + UsingQhullLib uq(&q); // Normally created in a method using 'this' + + try{ + Qhull q2; // If qh_QHpointer, QhullQh() calls usinQhullLib() + UsingQhullLib uq2(&q2); + QFAIL("UsingQhullLib did not fail."); + }catch (const std::exception &e) { + cout<< "INFO : Caught " << e.what(); + } + } + Qhull q3; + UsingQhullLib uq3(&q3); +}//t_UsingQhullLib + +void UsingQhullLib_test:: +t_methods() +{ + Qhull q; + UsingQhullLib 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, UsingQhullLib::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 UsingQhullLib_test:: +t_cleanuptestcase() +{ + UsingQhullLib::unsetGlobals(); +}//t_cleanuptestcase + + + +}//orgQhull + +#include "moc/UsingQhullLib_test.moc" + diff --git a/cpp/qhulltest/qhulltest.cpp b/cpp/qhulltest/qhulltest.cpp new file mode 100644 index 0000000..3d7ad97 --- /dev/null +++ b/cpp/qhulltest/qhulltest.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/qhulltest/qhulltest.cpp#45 $$Change: 1095 $ +** $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ +** +****************************************************************************/ + +#include "../road/RoadTest.h" // Before RoadError.h for precompiled headers +#include "../road/RoadError.h" + +#include <iostream> +#include <sstream> +#include <string> +#include <stdexcept> + +using std::cout; +using std::endl; + +namespace orgQhull { + +void addQhullTests(QStringList &args) +{ + TESTadd_(add_Qhull_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_UsingQhullLib_test); + // needs review + // qhullStat + TESTadd_(add_Qhull_test); + }//--all +}//addQhullTests + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + QStringList args= app.arguments(); + 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(); + } + return status; +} + +}//orgQhull + +int main(int argc, char *argv[]) +{ + return orgQhull::main(argc, argv); // Needs RoadTest:: for TESTadd_() linkage +} + diff --git a/cpp/road/RoadError.cpp b/cpp/road/RoadError.cpp new file mode 100644 index 0000000..2400a44 --- /dev/null +++ b/cpp/road/RoadError.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/road/RoadError.cpp#11 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ +** +****************************************************************************/ + +#//! RoadError -- All exceptions thrown by Qhull are RoadErrors +#//! Do not throw RoadError's from destructors. Use e.logError() instead. + +#include <iostream> +#include <sstream> +#include <string> + +#include "RoadError.h" + +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 &e) +: error_code(e.error_code) +, log_event(e.log_event) +, error_message(e.error_message) +{ + cerr << "FIXUP RoadError copy construct\n"; +}//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 &e) +{ + error_code= e.error_code; + error_message= e.error_message; + log_event= e.log_event; + cerr << "FIXUP RoadError assignment\n"; + 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/cpp/road/RoadError.h b/cpp/road/RoadError.h new file mode 100644 index 0000000..c64d209 --- /dev/null +++ b/cpp/road/RoadError.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/road/RoadError.h#15 $$Change: 1096 $ +** $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef ROADERROR_H +#define ROADERROR_H + +#include "RoadLogEvent.h" + +#include <iostream> +#include <sstream> +#include <stdexcept> +#include <string> + +using std::endl; + +namespace orgQhull { + +#//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: +#//Class fields + static const char * ROADtag; + static std::ostringstream global_log; //! May be replaced with any ostream object + +#//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. + +public: +#//Constants + +#//Constructors + RoadError(); + RoadError(const RoadError &e); //! 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&); + ~RoadError() throw() {}; + +#//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(); } + +#//Virtual + virtual const char *what() const throw(); + +#//GetSet + bool defined() const { return log_event.defined(); } + int errorCode() const { return error_code; }; + // FIXUP std::string errorMessage() const { return error_message; }; //! Populated by throw + RoadLogEvent roadLogEvent() const { return log_event; }; + +#//Update + void logError() const; +};//class RoadError + +}//namespace orgQhull + +#//Global functions + +inline std::ostream &operator<<(std::ostream &os, const orgQhull::RoadError &e) { return os<< e.what(); } + +#endif // ROADERROR_H diff --git a/cpp/road/RoadLogEvent.cpp b/cpp/road/RoadLogEvent.cpp new file mode 100644 index 0000000..7c1b26b --- /dev/null +++ b/cpp/road/RoadLogEvent.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/road/RoadLogEvent.cpp#8 $$Change: 1053 $ +** $DateTime: 2009/10/02 22:00:28 $$Author: bbarber $ +** +****************************************************************************/ + +#//! RoadError -- All exceptions thrown by Qhull are RoadErrors + +#include <iostream> +#include <sstream> +#include <string> + +#include "RoadError.h" + +using std::cout; +using std::endl; +using std::ostringstream; +using std::string; + +#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 +#endif + +namespace orgQhull { + +#//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 '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/cpp/road/RoadLogEvent.h b/cpp/road/RoadLogEvent.h new file mode 100644 index 0000000..44f0510 --- /dev/null +++ b/cpp/road/RoadLogEvent.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/road/RoadLogEvent.h#9 $$Change: 1094 $ +** $DateTime: 2009/11/24 20:04:16 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef ROADLOGEVENT_H +#define ROADLOGEVENT_H + +#include <ostream> +#include <stdexcept> +#include <string> + +namespace orgQhull { + +#//Types + //! RoadLogEvent -- Record an event for the RoadLog + struct RoadLogEvent; + +struct RoadLogEvent { + +public: +#//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) + }; + +#//Constants + +#//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 + +#//GetSet + bool defined() 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; }; + +#//Conversion + + std::string toString(const char* tag, int code) const; + +private: +#//Class helpers + static bool firstExtraCode(std::ostream &os, char c, char *extraCode); + + +};//class RoadLogEvent + +}//namespace orgQhull + +#endif // ROADLOGEVENT_H diff --git a/cpp/road/RoadTest.cpp b/cpp/road/RoadTest.cpp new file mode 100644 index 0000000..9a9bced --- /dev/null +++ b/cpp/road/RoadTest.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/road/RoadTest.cpp#8 $$Change: 1057 $ +** $DateTime: 2009/10/22 20:38:42 $$Author: bbarber $ +** +****************************************************************************/ + +#include <iostream> +#include <stdexcept> + +#include "../road/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/cpp/road/RoadTest.h b/cpp/road/RoadTest.h new file mode 100644 index 0000000..9a478da --- /dev/null +++ b/cpp/road/RoadTest.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 C. Bradford Barber. All rights reserved. +** $Id: //product/qhull/main/rel/cpp/road/RoadTest.h#11 $$Change: 1097 $ +** $DateTime: 2009/12/04 21:54:00 $$Author: bbarber $ +** +****************************************************************************/ + +#ifndef ROADTEST_H +#define ROADTEST_H + +#include <QObject> +#include <QtTest/QtTest> + +//FIXUP -- test that compiler sets QHULL_USES_QT. +#define QHULL_USES_QT 1 + +namespace orgQhull { + +#//Types + //! 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 + +protected: +#//class variable + 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 + +#//Test slots +public slots: + void cleanup(); + +public: +#//constructor, destructor + RoadTest() { s_testcases.append(this); }; + ~RoadTest() { s_testcases.removeAll(this); }; + +#//Helper + void recordFailedTest(); + + +#//class function + 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/cpp/user_eg3.cpp b/cpp/user_eg3.cpp new file mode 100644 index 0000000..d45ac62 --- /dev/null +++ b/cpp/user_eg3.cpp @@ -0,0 +1,134 @@ +#//! user_eg3.cpp -- Invoke rbox and qhull from C++ + +#include <cstdio> /* for printf() of help message */ +#include <ostream> + +#include "RboxPoints.h" +#include "Qhull.h" +#include "QhullError.h" +#include "QhullFacet.h" +#include "QhullFacetList.h" +#include "QhullLinkedList.h" +#include "QhullQh.h" +#include "QhullVertex.h" + +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\ +\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) +{ + 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; + } + readingQhull++; + readingRbox= 0; + if(strcmp(argv[i], "qhull-cout")==0){ + qhull.setOutputStream(&cout); + } + }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(rbox.isEmpty()){ + cerr << "Enter dimension count coordinates. End with ^Z (Windows) or ^D (Unix).\n"; + rbox.appendPoints(cin); + } + 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; + }else if(qhull.useOutputStream){ + return 0; + }else{ + QhullFacetList facets= qhull.facetList(); + cout<< "\nFacets created by Qhull::runQhull()\n" << facets; + } + return 0; +}//user_eg3 + + diff --git a/html/index.htm b/html/index.htm index 8b72161..75026cf 100644 --- a/html/index.htm +++ b/html/index.htm @@ -6,7 +6,7 @@ content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Microsoft FrontPage 2.0"> <title>Qhull manual</title> -<!-- Navigation links +<!-- Navigation links NOTE -- verify all links by 'grep href=' 'grep name=' add # 'sort /+7' index.htm --> @@ -22,13 +22,13 @@ href="http://www.qhull.org/news">News</a> about Qhull<br> <b>To:</b> <a href="#TOC">Qhull manual: Table of Contents</a> (please wait while loading) <br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> <hr> @@ -44,11 +44,11 @@ diagrams, furthest-site Delaunay triangulations, and furthest-site Voronoi diagrams. These structures have applications in science, engineering, statistics, and mathematics. See <a -href="http://www.ifor.math.ethz.ch/staff/fukuda/polyfaq/polyfaq.html">Fukuda's +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. For a detailed introduction, see O'Rourke [<a href="#orou94">'94</a>], <i>Computational -Geometry in C</i>. +Geometry in C</i>. </p> <p>There are six programs. Except for rbox, they use @@ -60,7 +60,7 @@ the same code. furthest-site Delaunay triangulations <li><a href="qhalf.htm">qhalf</a> -- halfspace intersections about a point <li><a href="qhull.htm">qhull</a> -- all structures with additional options -<li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagrams and +<li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagrams and furthest-site Voronoi diagrams <li><a href="rbox.htm">rbox</a> -- generate point distributions for qhull </ul> @@ -72,21 +72,21 @@ for hull volume, facet area, multiple output formats, and graphical output. It can approximate a convex hull. </p> <p>Qhull handles roundoff errors from floating point -arithmetic. It generates a convex hull with "thick" facets. +arithmetic. It generates a convex hull with "thick" facets. A facet's outer plane is clearly above all of the points; its inner plane is clearly below the facet's vertices. Any exact convex hull must lie between the inner and outer plane. <p>Qhull uses merged facets, triangulated output, or joggled input. Triangulated output triangulates non-simplicial, merged -facets. Joggled input also +facets. Joggled input also guarantees simplicial output, but it is less accurate than merged facets. For merged facets, Qhull -reports the maximum outer and inner plane. +reports the maximum outer and inner plane. <p><i>Brad Barber, Cambridge MA, 2003/12/30</i></p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> @@ -132,17 +132,17 @@ Contents </a></h2> furthest-site Delaunay triangulations <li><a href="qhalf.htm">qhalf</a> -- halfspace intersections about a point <li><a href="qhull.htm">qhull</a> -- all structures with additional options - <li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagrams and + <li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagrams and furthest-site Voronoi diagrams <li><a href="rbox.htm">rbox</a> -- generate point distributions for qhull </ul> <p> <li>Related URLs <ul> - + <li><a href="news:comp.graphics.algorithms">Newsgroup</a>: comp.graphics.algorithms - <li><a + <li><a href="http://exaflop.org/docs/cgafaq/">FAQ</a> for computer graphics algorithms and <a href="http://exaflop.org/docs/cgafaq/cga6.html">geometric</a> structures. <li>Amenta's <a href="http://www.geom.uiuc.edu/software/cglist">Directory @@ -150,10 +150,10 @@ Contents </a></h2> <li>Erickson's <a href="http://compgeom.cs.uiuc.edu/~jeffe/compgeom/code.html">Computational Geometry Software</a> </li> - <li>Fukuda's <a + <li>Fukuda's <a href="http://www.ifor.math.ethz.ch/staff/fukuda/polyfaq/polyfaq.html"> introduction</a> to convex hulls, Delaunay triangulations, - Voronoi diagrams, and linear programming. + Voronoi diagrams, and linear programming. <li>Stony Brook's <a href="http://www.cs.sunysb.edu/~algorith/major_section/1.6.shtml">Algorithm Repository</a> on computational geometry. </li> @@ -173,12 +173,12 @@ Contents </a></h2> </ul> </li> <p> - <li><a href="qh-in.htm">Qhull internals</a><ul> - <li><a href="qh-in.htm#performance">Performance</a> + <li><a href="qh-code.htm">Qhull internals</a><ul> + <li><a href="qh-code.htm#performance">Performance</a> of Qhull</li> - <li><a href="qh-in.htm#library">Calling</a> Qhull + <li><a href="qh-code.htm#library">Calling</a> Qhull from your program</li> - <li><a href="qh-in.htm#enhance">Enhancements</a> to + <li><a href="qh-code.htm#enhance">Enhancements</a> to Qhull</li> <li><a href="../src/index.htm">Qhull functions, macros, and data structures</a> </li> @@ -198,15 +198,15 @@ Contents </a></h2> halfspace intersections about a point, Voronoi diagrams, furthest-site Delaunay triangulations, and furthest-site Voronoi diagrams.</p> -<p>For convex hulls and halfspace intersections, Qhull may be used +<p>For convex hulls and halfspace intersections, Qhull may be used for 2-d upto 8-d. For Voronoi diagrams and Delaunay triangulations, Qhull may be used for 2-d upto 7-d. In higher dimensions, the size of the output -grows rapidly and Qhull does not work well with virtual memory. +grows rapidly and Qhull does not work well with virtual memory. If <i>n</i> is the size of -the input and <i>d</i> is the dimension (d>=3), the size of the output +the input and <i>d</i> is the dimension (d>=3), the size of the output and execution time -grows by <i>n^(floor(d/2)</i> -[see <a href=qh-in.htm#performance>Performance</a>]. For example, do +grows by <i>n^(floor(d/2)</i> +[see <a href=qh-code.htm#performance>Performance</a>]. For example, do not try to build a 16-d convex hull of 1000 points. It will have on the order of 1,000,000,000,000,000,000,000,000 facets. @@ -243,23 +243,23 @@ href="qh-impre.htm">Imprecision in Qhull</a>). </p> <p>If you need a short code for convex hull, Delaunay triangulation, or Voronoi volumes consider Clarkson's <a -href="http://netlib.bell-labs.com/netlib/voronoi/hull.html">hull +href="http://www.netlib.org/voronoi/hull.html">hull program</a>. If you need 2-d Delaunay triangulations consider Shewchuk's <a href="http://www.cs.cmu.edu/~quake/triangle.html">triangle program</a>. It is much faster than Qhull and it allows constraints. Both programs use exact arithmetic. They are in <a -href="ftp://netlib.bell-labs.com/netlib/voronoi">ftp://netlib.bell-labs.com/netlib/voronoi</a>. +href="ftp://netlib.org/voronoi">ftp://netlib.org/voronoi</a>. Qhull <a href="http://www.qhull.org/download">version 1.0</a> may also meet your needs. It detects precision problems, but does not handle them.</p> -<p><a href=http://www.algorithmic-solutions.com/enleda.htm>Leda</a> is a +<p><a href=http://www.algorithmic-solutions.com/enleda.htm>Leda</a> is a library for writing computational -geometry programs and other combinatorial algorithms. It +geometry programs and other combinatorial algorithms. It includes routines for computing 3-d convex -hulls, 2-d Delaunay triangulations, and 3-d Delaunay triangulations. -It provides rational arithmetic and graphical output. It runs on most +hulls, 2-d Delaunay triangulations, and 3-d Delaunay triangulations. +It provides rational arithmetic and graphical output. It runs on most platforms. <p>If your problem is in high dimensions with a few, @@ -268,7 +268,7 @@ href="http://www.cs.mcgill.ca/~fukuda/soft/cdd_home/cdd.html">cdd</a>. It is much faster than Qhull for these distributions. </p> <p>Custom software for 2-d and 3-d convex hulls may be faster -than Qhull. Custom software should use less memory. Qhull uses +than Qhull. Custom software should use less memory. Qhull uses general-dimension data structures and code. The data structures support non-simplicial facets.</p> @@ -408,10 +408,10 @@ the last point is <i>n-1</i>.</p> </ul> <p>Except for bounding box -('<a href="qh-optq.htm#Qbk">Qbk:n</a>', etc.), drop facets +('<a href="qh-optq.htm#Qbk">Qbk:n</a>', etc.), drop facets ('<a href="qh-optp.htm#Pdk">Pdk:n</a>', etc.), and Qhull command ('<a href="qh-optf.htm#FQ">FQ</a>'), only the last -occurence of an option counts. +occurence of an option counts. Bounding box and drop facets may be repeated for each dimension. Option 'FQ' may be repeated any number of times. @@ -425,7 +425,7 @@ and a window scroller (e.g., <tt>peruse</tt>). </p> <p>To write the results to a file, use I/O redirection or '<a href="qh-optt.htm#TO">TO file</a>'. Windows 95 users should use -'TO file' or the console. If a filename is surrounded by single quotes, +'TO file' or the console. If a filename is surrounded by single quotes, it may include spaces. </p> @@ -436,7 +436,7 @@ href="qh-optf.htm">formats</a>). You can list vertex incidences, vertices and facets, vertex coordinates, or facet normals. You can view Qhull objects with Geomview, Mathematica, or Maple. You can print the internal data structures. You can call Qhull from your -application (see <a href="qh-in.htm#library">Qhull library</a>).</p> +application (see <a href="qh-code.htm#library">Qhull library</a>).</p> <p>For example, 'qhull <a href="qh-opto.htm#o">o</a>' lists the vertices and facets of the convex hull. </p> @@ -529,9 +529,9 @@ graphical viewer</a></h3> <p><a href="http://www.geomview.org">Geomview</a> is an interactive geometry viewing program for Linux, SGI workstations, Sun workstations, AIX workstations, NeXT workstations, and X-windows. -It is an +It is an <a href=http://sourceforge.net/projects/geomview>open source project</a> -under SourceForge. +under SourceForge. Besides a 3-d viewer, it includes a 4-d viewer, an n-d viewer and many features for viewing mathematical objects. You may need to ftp <tt>ndview</tt> from the <tt>newpieces</tt> directory. </p> @@ -556,7 +556,7 @@ href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometr <h2><a href="#TOC">»</a>Qhull internals </h2> <blockquote> -<p>See <a href="qh-in.htm">Internals</a>.</p> +<p>See <a href="qh-code.htm">Internals</a>.</p> </blockquote> <h2><a href="#TOC">»</a><a name="bugs">What to do if something @@ -637,7 +637,7 @@ href="http://www.qhull.org/news">qhull-news.html</a>.</p> <pre> C. Bradford Barber Hannu Huhdanpaa bradb@qhull.org hannu@qhull.org - + c/o The Geometry Center University of Minnesota 400 Lind Hall @@ -654,7 +654,7 @@ thanks to Albert Marden, Victor Milenkovic, the Geometry Center, and Harvard University for supporting this work.</p> <p>A special thanks to Mark Phillips, Robert Miner, and Stuart Levy for running the Geometry - Center web site long after the Geometry Center closed. + Center web site long after the Geometry Center closed. Stuart moved the web site to the University of Illinois at Champaign-Urbana. Mark and Robert are founders of <a href=http://www.geomtech.com>Geometry Technologies</a>. Mark, Stuart, and Tamara Munzner are the original authors of <a href=http://www.geomview.org>Geomview</a>. @@ -664,7 +664,7 @@ Solutions, Inc.</a> of St. Paul, Minnesota for their support of the internal documentation (<a href=../src/index.htm>src/index.htm</a>). They use Qhull to build 3-d models of heart chambers.</p> -<p>Qhull 1.0 was developed under National Science Foundation +<p>Qhull 1.0 and 2.0 were developed under National Science Foundation grants NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. If you find it useful, please let us know.</p> @@ -683,8 +683,8 @@ Computing Surveys</i>, 1991, 23:345-405. </p> <p><a name="bar-dob96">Barber</a>, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The Quickhull Algorithm for Convex Hulls," <i>ACM -Transactions on Mathematical Software</i>, Vol. 22, No. 4 (Dec. -1996), p. 469-483 [<a +Transactions on Mathematical Software</i>, 22(4):469-483, www.qhull.org +[<a href="http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/">http://www.acm.org</a>; <a href="http://citeseer.nj.nec.com/83502.html">http://citeseer.nj.nec.com</a>]. </p> @@ -698,7 +698,7 @@ Seidel, "Four results on randomized incremental construction," <em>Computational Geometry: Theory and Applications</em>, vol. 3, p. 185-211, 1993.</p> -<p><a name="devi01">Devillers</a>, et. al., +<p><a name="devi01">Devillers</a>, et. al., "Walking in a triangulation," <i>ACM Symposium on Computational Geometry</i>, June 3-5,2001, Medford MA. @@ -708,7 +708,7 @@ unified approach," in <i>Proc. 17th Inter. Colloq. Automata Lang. Program.</i>, in <i>Lecture Notes in Computer Science</i>, Springer-Verlag, 443:400-413, 1990. </p> -<p><a name="edel01">Edelsbrunner</a>, H, <i>Geometry and Topology for Mesh Generation</i>, +<p><a name="edel01">Edelsbrunner</a>, H, <i>Geometry and Topology for Mesh Generation</i>, Cambridge University Press, 2001. <p><a name=gart99>Gartner, B.</a>, "Fast and robust smallest enclosing balls", <i>Algorithms - ESA '99</i>, LNCS 1643. @@ -750,17 +750,17 @@ href="http://www.qhull.org/news">News</a> about Qhull<br> <b>Up:</b> <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a> about Qhull<br> <b>To:</b> <a href="#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> <b>Dn:</b> <a href="qh-impre.htm">Imprecision in Qhull</a><br> <b>Dn:</b> <a href="qh-eg.htm">Description of Qhull examples</a><br> -<b>Dn:</b> <a href="qh-in.htm">Qhull internals</a><br> +<b>Dn:</b> <a href="qh-code.htm">Qhull internals</a><br> <b>Dn:</b> <a href="../src/index.htm">Qhull functions, macros, and data structures</a> <!-- GC common information --> diff --git a/html/normal_voronoi_knauss_oesterle.jpg b/html/normal_voronoi_knauss_oesterle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f46d421274edd97de13d25e306985c43e872165b GIT binary patch literal 23924 zcmbTe1ymf((=WU@K|*ksu($<xSO~#_1$TE3?iPXscY?cHa1ZVdi!JWK-R*9k=YQY# z-g~}tzWaT%XLe?*dwQyRs;jGh)w8b)uj_z!pCzOv05C8B01Wg4czpo~h$)GSswgP& zQ<$4DTYWV(r*LIsVWpsRak8{Cr;z?EN%8rMxFm%uH#<EOg@cQsjis{(g%AZVE6VE< zKn#EgkAR2(kBEqXh=hcQjPecz<;@!uoVOTg@9=R52=H<6@Q6sM$%%-8BzSlfOcX#G zT6zY0LULwSW;#}CI(oXljlduwA)z3nV56X5(-Gkj(fxnkUONGp$S}Mx*>EtF09Z^I zI82z=UH~~%NCcRFHo$*27+5$czevb$P*9;2>fZriVc_6k;o%Sv;NhXQeW2w4cuWMW z_iUnw*ouZolnyxT0kJvAz>n2kxJpxJR2)W*-`=3$;S&%NQPa@U(KB#zar5x<@r!*D zmync_{;aH`s-~`?sby?pYG!U>Y31bX;_Bw^;TiZnC^#haM_62ZLSj<#&y>{My!?W~ zqT-U$n%cVhhQ_AmmhPV3zW#y1q2cKn@a)|D!Xjj2b8CBNckj>s!TH7I)%DHo-TlK~ zxnKZr|B40u{#UU7LoQ6HT(I!)aPUZf<${5AgYIyc@CfhO5V1rRkqjNMDcJ*%aX!Z8 zRCm1rawwhQ8aYm(;8AgIP@n%5?H|eh?*#ky|4Xv}670X_f&kFqV4x2V4if+ZjPVU^ zPn$fXdXS{bs%@hWU2{TzxYG3jcxb^>6D37Pk#&IOEM*CWe@|C^<Vc|95H^wjS@rMf z9(ellz|uhi0<cpk$)g3&G)y)46FD7N?15*hp;UX}!YCg(0b61Vn6`&h_P?hD*@%~a z%V&?-JJ;k7rU&5JB&J6=vs^h9hd|j6v8shZIf+}|cFKWaBI5D?v;=MR=l^l5EM@s6 z5gY)ND>%Lb%Owja+yCJ;;tQPP|Hdoy#yW~&0C^ud8mKI`dA0yr;lg-m1AS0dw*SKw zl)>hIdBrjECm!cd)$@^K`P&&;%96r`8Dam5oySL#s#}-sNC(sFXi<W^J#7?#)<;mZ znT&%l_@_@AT1zJ?LitPxdLajn^0@>Z%+EZWC+N*hp_L-O;1i02pv@DCO9x2*OG}3J zZziMblMdLIK!9<0SdPXBAU_I(wVoo~x`p67%Un_M2_G<ICOX_45@JT#*}NzpOql~- z0i6ouAL~nuvTQV+&G$?Cm>j(11N1(Oe(N~n-(s?-nz^QGi9m$-nh23f-6uSYQs$LN zN{ee`@^+~Qgm*Fgpfp}lsA}3K|7yjg8pj?M4;znz(66Y_$ASQm3}aLH+cAn^zVu&( z=wSKj?+QAvvXRgKWj%~R7UMH39jxGgm9r@sL*j7&!}ND~&_;~HeChgN91{K!J|WwY zexU#^Rs;)od#a&;aVXCgmU2k~l59%@0YuvpTj|!NS-=X_*_LomA7>*&A9MbaOoRX5 zD)CU2`KQEn+BO^c=5Gm9o&H`USNH!wKwD9*eDA}qO|g3*5Ny$a)^PqS0z+rkk3?G% zuY<a;%~!Ynf_Ygcx`o6v`2}_<`2|jw<$FMz`o=F$)Z>9O6u$z4<wM5J3DizKR<20q ztnsB+0CTo+#@#jgJozf^T&-8~q<v5&LNB{z4f!hCh;8QHUHmy5aM^1vRBLM^PKrj_ z&?qhsQH@lTBv7{_jr6)){j69ujq(#IFve%+!727gvOtMC2C98B4e_>LLjO03>Z!g+ z(;MR0?T8xJOLvmW0o4CrdZ5(;mice5K?fV~f35o81QrM&{J%PD5{WW@=`%j`IV3_= z_Mhh<07FL4rnDJZr-5886BdtS6#g$ELeT)&N5i072PNRqJ17}J36y;VB@WUJ&>D1o zG7bN!0Uc6I@EQewm0sLG9H*&-O@i(h)*lUhoIj(UR5cwtgrMoRj_zb7jRR(<w}K0K zZaR+usfTySRdO>IEyraT>%lu6j2;+QRg9AzTdx57+bx%;sWN)Js3NtxZ&E<;)lOf+ z9y-C^V0?=Y|JFHaq|AobPD6{ecJPw5OOTlm(BW49y6c9frj4(Z`THsQ^nDUOoXJ!? z*z*yyYr+Plxop3`d!5dndsXx|p+isA6)=aa?&-UWlEl>D)L?<GJhD(E4TBKP>7$IC zx>H)20Wf(sIk)2qBzmaErdE$hMu#HZNl07I?-mAm&kPR7G0zc9x={qrgNm)=hKU5; z&7G5>?%hV-y#kPL$TMh;@VM+xZEe_V<Ege@G$cI8Pszfcp3BJQd(|5rW)sg0s=Me6 zVZVMi*e2JBh)A7is88Kh#4Tr+d;cf4#K;duonneMO{u2F!*=>$(=_xW6$a&AL`~)A ztu<WcNYbb(Yts5lpY)UZ#7~nv<u>dc8+WQ2n;s-o7UO&VrR;K=^VjX%!_(tJ!jpP^ zw!eqzO=G|DB>HQVuBX>x-v&A13j=2>yMhI>YCkR$R3v=N_d4E=F5v`M;_(O1uwXk5 zQ%0#Ot;!7MegsfGrA&w@0PB_eOx@-8ZMnXFmHqf8RiYEriY!Cs6$ikrQ<Sx2va1oJ z7?x@$@QW@!mJ|4q%cS^MjY_-!(H5vKU>ZfJH09wy^-JPE>IBuEFzzX+I<YXw{-Zs4 zxHR+*f3+vukwLBwVO!CF8kj0q&!#5_wGV&QSNHE&Z-APPzk@#<$F{^3s`39?5U6?h zI|TkA^!-=Ou;jmX<8OgfA3tLS^Odz%W0J+w(hq~n>K0ZNdP2B#(t+5_40;~Jg+LtJ zG9~RAiJEUUBCh~Pjqz>!9Mb0&u(o9Y9^I1CG1OQA>xf-wou2S`B3}V<)AR8b$Bk<B zw=o!_TMzRUL7m{N$5hj)SHK_(sKWia*2697^m!5H*_z&NM0{F6U2bD!p~_Z1y0}Tj zxMfv&BH<OVu@J5Bl`$)WdxGJCjl6;ttDFD}nGfEzs41#UR=b^1i{UKJcv$B>1%1Tz zh;u)y=>Ftfd*9^<M^DbukatfkPts?Emow6rqUZ|KyK5qs+L<`@N7IUQW(TsZkl17o zf@>Ima#=Urkwbj!f~X85ngs2NmO-OcS34tZ-u-mUF{(Aug_U*<U}E8%i@V^-KDJM; z*b(<r-X9G$=a!o+`@Z1xd5l+pki7}-L+A{_lV*^UdmhdaV#ZBJsa~&P+<snzkbysP z9!OOO?wYH01D>BdpyV#{xAwORV*{`Ih>kXgmje<Xt!8UR=_-4Q`UWwo%fagYyt|+2 zF!!kkg4Ql5dVRSXyk4YaD;0^!`8C%`3VpSAFw)s#oTsbq!r)9<^|-3%t75+bb~SAa zX@^U)yazw%*q>9}5SZSBB_3R(ZBQJzDo-nkxJdfb(JcgexblE$&c%xsn?22c1!xLL znuRQ697ku1lb<o{x6vXB()$TGwcJq2-gNWX_*&nibhbqwwID{CPi1nq$3O35jJyJ( zD9QU<p3y()Av8qa6|{Ox%pf4W_*>?%H$b?-trkmKSmF(l_5A(gU8*u{e*i;;I-F|x z;UyaZA*!*R_K$m~<egvGp%YnYytS6I$HJu!*{Y70$_w*1&}qDi**QrDb9qjL=WxFS zdD7H<;OBK)20RKns?6>rXS|+g2C0h2O><<0Niu~Eo$`m@dA#pWsa1v4m_8L9-~+(? zu4xX%vP0Gc0uuXF#`RzPJbs=bFa|{h+iJ^)2c>EUAH5IVy0r222T!;sq0oTWG4Tka zCVb8OJ`VT?9=y3JuWHb;*s@CuPg~n;ce(%a3Yg&nJz(xlqU04VtQ_*^yPlmSZJLb; zq;EBw3Hv+B(JYJ)yUK*ipbq9rCGDc`U<;@Qvd3_|ocIw{HB>H3BD8VeaGSK(mnNv& zRrc<rEzxEltKQ5qfB)M@ED-J)OgzY!wy=0xIz4f~XZ3jLhC;?M8VLM<iYMW<E&dr^ zfd5+pawm;HUl!IH=1UNq!LQMB0Stwb7yTfXbm6J>F|D=s^0O7XD<o&zS3nN6xiwQ{ z#ab!dmzvms<AJLRePk>uumJ+kipB(qRFA;6>Lq@3DaLqh`|L=g7^4E1<*M}uLdM`* zz@^b+&!1s;uBnB?B>X1r0zB-jO+pLp`^0C->9%4SinMWcLvA<w3BHOE;)Rn0CVz3B zkD#F6nF%@=vT+cp8!Q<0$EbYv#>psjai21t8}HLxQS;pe0qVgxOvaj%&IG%`es>^= z!=cW6NWDxX_Y3YNffi@k-pA!Kw9BqP4r|4^8+&KBKkR(RyE0eJBSHwVSfm(wnt&8D zcI)D9o5v>cgiVcX!x51LwLz)@$`|PrgTjd;Vt%=6tUT|e3zlC26H**ZNC)3f^owa1 z)I~Q(=xkR9lxKQK**6vIu;Wpq+ljrRR`as7E+0eN(o*t3oqc{lrT(Z1rD;1j1vlH8 zlgVl)uI5!7^3%6vuK-xsv<+K67X?hqIY$Sy+7GEdK$7Ms9HRc<120RX%xO!*3`|Wu zZib#6!fkcs4PC!u&-kU)9!t{WWh_XKFZPIu$Gc)Cd=#g2?1;<s$?r~()oPZ!P3>nD z60Y7;I{h2zbzhCbgX5cJJ^JO3<&Gb2zp`SGw)lb+RqPDnARY!8M0|NhQIWG!>wyZ5 z85Ji~20ZW0)WoKO6>w|>691I(aBmQ5VQIZVRE)k5-YR+pRMrCHc2718YQLutHbh)F z&72i|<?ld~;tbaw^OQiI8`*}$ue!m*y#ineL5YT%)hX#4<JY`GOSBDs85VbyQssS_ zk(gK+d{T)^@SMjZ4FX$1dxhwx3q69dV@x*Q0|+?r5m!S)`vJ<kh&Pc8Be~Ww1GhkT z5^^057QgcYv#g?tVp(A0M+u4BKgB{CSFja#D6=#^T65grb|o7T0*7|GQ3i{4V`3*w zvJB^1h}-q%KSpuZyK@QL=qKE3+Z<o6@<y-O-(+3z75Yzsosaotnz@)ipLG>DkT#=; zCUL^3NMMZa0i22bAh=~@WknMO1QoVHnHdPVIuaMA+k`3cXcC^==`i5TcI%OP)TIiE z{S*7WxJ|c%3zDp&UpJKlipr)Na>5)vYgG2H0GlaC5O-|HX{r%*nqGBuXp&d(E5P(4 z{gVRl<-QdAE^PhW-X0!UZ8O+&+5HOGs*et1Q=#k|FYs|JFmFwXxfZt#^;>5Qcu?i~ zl7|8y>&}OU4#sQ}46}*px3!_RMwV29>#k(^H)Pj^R5eo_U=KG)=qn&8-;5yo5qLMz zymcsrY+INA4Zd}b%G%47Fp8SIJ?(jF!LQB_4a^@^LJg*bAkWS9$*Zk$^!sRBo85v6 zRGU+^OIEFakZJ1dWQ<D}pNpV>vLsc+sbz!OVCkxlGe_zozr0i_4me<LipV?pLj!J3 zPp?YJ2xj_|?aA`^qmSRrbH~QMl<*UVULSR28EO&x7A;RE_FnzRv#=WaUtEkF4_q3k zHJgObceLn}QjeE_7)XZ6szB!ik-r|!KgZ2@T&UTbgm;HJG=GnO-QtGGy1)MNzejpS zo|dZHQ1T3rEw{u)o(E_zHTfynuYmT~)LwGzXGqLXfbZl0fR&bZm&9eao^vQTw(`!? z>rRhaJ1>Mmv|k;#B4q@^sBmmaXV<abUB&$Xymu&#+A|6Z)z-1>^eJSwrJ=ZwjTwoZ zN(><+-(>tiIaq&)IDOsvh!4+IcZx4ODz2nQ{7n=z(RhDbIkQPNQia7C$NmZ^6h#NK z-;DI5!X3A|36({~aYv?*;JWZqTqFLBBqo)LtX?)v&K4TDzp8BPJ)s59tvj+*<g}<= zFZ+XDgo!UJ0TGuGW-W4`|5SxMaTJrpzRB#?^9$18o!Fp%DnV<uEYV&}s+q;ipSJgN z`-*=mA-R(12T{I{h`JuW>yb&8o<E_8P5Sh;W`NyiQ88Gos=BPD?wdw}EyLh~A=pQ> zLQb$}lbK;jq}5brRtaL;LxRCU%gXk0=nyUOFnJA^r2N=K;B<j8KuA8F5LuBp&L1d$ zVe%c>JTfnp#$tuQpbU`@-gCy(<c9-CDdr?u-T~5Qz`meF))J9wL&v+(CvANgsJjEW zH+cmFz)ZAcY3-!U!q-SGDUaHhY@adaotYI`qxaq<$5EyFY<ei?vQmAx?YveFCjZ<u z&$;NVtG7FTXuaIK=1o$GK~V*M=X5H9R{v89jVExZJ~ogR#LoI>ZR=1MDa6*Kwgp@d zqQm(`C6eu3BfGdTAS6Q0BUBa#ndU~+T-YL&=32gcFqz_f#*hw*A9c^%{32pdsZ*@y zzGV$FK(JYG!jT*`%4V65?gnI|3SJ`fI*GX!?zt>;)ss6O8)aWc4R@#TP@7)HQ9~Vq z2|er*!XVtOKCz>|(9+CzOHx=VF^)s>JA0A?b=TDY?yzJpHkG*V`t#-a=+Sme0C``K zx^%+F!v$3gN6Qf+i#5&GAk^jNv=TisM3q{`QP)VEz7wU9+L)u!UKQC<YrEwt)jLH8 z$EPOILtab)R_9K}OJ+&_Dg*Bi)1boO2fQxy|DjTg@I?mOAIbAjQ06^R=*(rp3}w_P zxr>PYD}anyMUWhYyBW847!B|9yd&HUG7rpM!_*y^ZSWRrLa>Pa^W(xpTv@7*_#~SI z#Fs(F%fpUFBReubF$%VLh)YB?Y`SLpR)pnr=aD(~&$j8#jri&HA0ey3s0ry^L(=0j zsG%{~rHg))yo>&|b*MR?%(1#mSeXyCNhUXB{;p(T|5~q-lSb}TZ++7mkca5V$jR~A z{-mdx83YPquo5;jdJ7cx{&`5s4JtP<D8m<X`k+W~b29MjA*?KSKeA*cf#rQ;q-^|n zPiTw_?LEwLtgawh<BT|yB7yUxDcfSV*9SM@@_{%@4;cOwvpAXXLUafE<!v;WKiRH; zuLuHvjmB(&k<>o{l5HU+lhWotD93-rLto&Vpz(S>F#f-RBs01`5Ka>mj*(!HRf0lE zP*Vhjn4qycG*pM8Fr!LFe@!r=QOUt^tz5JHgIUidyr0&LMO&*{bCdh=v3mIo?<cZF zt{)D?mXJ{%e%EBDo3v(18p<YBS0!SDp>g?X7z(tlxk5P`C0zx<R=*nI#u8`eSAe)b z)Nho$cN7jIcu}3$Pc2wY)zBV#EPOoYU5>uSE!y<T5z0vT%7`pmD@V`!3eeI<P?&O! zo^N-$PNlo@an-i9?-nL$6PByXF|9?B2hcq>1PeOH7_gD+>)B>|eX}hfXb&}XgDvlQ zEXM$e%`|wb++^)%p<NS%j#xf?R}T0Smk0DMO^mfJu4_27bq#l<AQX2BUOI^2QzKg@ zTi^T+dxVNzcSQNg2CMV>s&h}!H?atJS=|>fXH+K!T+kJDMa#R>cD4~g0v9Q(=;4C% zmf$aRf~ddSAwk}4W%A3+ka(}o=B$s{UL4$DVXWxw&-DK^aBIO}6CrW>`CuFd==^4V zxKL5h;Gri@rre+Rb?Z03LG+IL%K-JLC5asJ?}+4geZ0&|+1FdyeC5YvehvGn?d?r) zHqs0X*BhOD*Bc$5M>1guBMV{^_9!IhFOQ|na}Uh+`pC%Qm4n$+kNua5KLzeJM;N>b z@s5JS$hod0%+`3ZUWCP*roK-*C*RVo>N$M2yH%=-SE$asuvql-{ka_G-W##TNKf)^ zMe-w~qduBDeVe8OX=M)SPH%Z3I+sjEi&U=}cLr_^M><Tj?BqhZ$4!V~$-#W51;2*_ zAv)7o1O@4;Sdikqx=ZoCgEg&OO?7R&F8DZ?t$nQSw`x-ad7_pCx$vYzY!us=+WCht zXCJ{dRDTy`yFPWfdNIqQ?w-ey+ii+lt`RHW4|7~;Z<tO@WKd;aPUfaQDJGtvL}|~{ z3hnDgT%l8mZlsZ_-GGi-$0VlN!sY1I%<7T&VpoQY)ZzT42!}`<_U0c7k|U|31e(R8 z%HCb9XF9?=u}Cky{{q_}E#TiZ0W4E{8(AV8RNCWIG;GlHquDr4>I7qcy2aK@y6zk| zalCfpXA&b=_cn=v6^Bf=`t5;N^u}JJSTRX|VeQg^(&DNZ6?@kO!yxPDsF3r+%n+{W zJA1LrouD>4@B3gAsx70auhM^zloaFz&Q;n#o`>*k?wPZN)d3-kx?R}4PE(+^z!K%I z<8My7$zgGOGAnuelcRGNl+w(QO1X8zW+@<VbS93k;0!Ffr25QpPV<Z{k%yY8N;8<! zpo(V7zZCfupavi@!5g5dEoZ53b$7LZlv&{|QfW!?kmm$lym<w<xy{w;^&cyy9o4R* zy#mTW8>)F<VuGFORUCbuk=g~2uRb8HR#w=0nfnwiLF7D0e%&_|PYrt4UrIsbC)rC` z0p-Q(DnTY;;;C=m&{JLkAIKG@*L~zS6-e%U8N+|%M@eF`5AK{*qHJYVn7XrXFInBp zHNtY$#BGZUntp9s@n6_NdIeN{z5%~Y?UC~e9lhjVS}f_2qm_N2I~Z6{X(ak4j;d`b zH7U}A!RS|!d>|?MGWg^qJG;~BH6L}gu|dN|6hUdQg@Oc7B~d+j5A~3sNP8iiE4aZm zUQbut-j*=VQUf|9sAkx7KjGC{++>*ta8&4hl8F;}<fL+B_hchgFdT4_g4v8l&9xjS zgK%Sbea)baaYcG8oAjk^x0NKyMNkZa1E>(GWil~i@-lU@88{LPb)7KmGUWcSF@pk| zMiHvWP*bVZSev;;LpP*28;v5If5wn8SCXrNMcc+xi*avi!h_K-cJZQ_za2Ae15JF0 z7FjD=gDf#MB`ug!V1pcwhC45MulbZG-_~2>(0;Y*ff@oRx(%0VM71=OhjYQl`LoD? z5bEds1^Dgg`UL)F4#L>}Nh=s7;~YV$W)L0aYA6<lwxsdGa*lfE*gbzV*?Ze4KFnFt zBvDpp0ym)K893c|JjvDjxrgEx5=iSJE3^^q;klx$ng%ikXa0El*#E3g9`tGLW3J&r zYQ{~O!`^|qlg=<dA+dmDHYwl+R}Co+;=b45L{iP_Y`7RO2+9y9&@*2mm~iw22uUAH zGmo;ehAlIV%M(cu>VM690HZCOvwfGdF8`Em$v>Q&xdxA1gmfFAVDx5Lz_5CTYjhP- zUl*7$1!DUwd=v;K-v<-@sZ)tMu4)r@4fjzM?+dVtU9NPkYB){hxK`FVi7%$IrpfZ0 zz+vh&43=eg9wZ$gU_3rRkQxu~?AYgi0nR9ZtY)ZO$f_{0qNmUue`}{p6W9z~+Ud>C zdJD;<DUd7;x!8%<*9JHqzEl{-;4&%5708hLvgy3E=N>}rPm3C}j!@QGnj48L7R<kq zvUgNkz_D9$ka)d8NMn+01a0Vk_sp}@$8_ck$BW`UlIuTlvkT^U57HgeSxqU_w^k2p zVNOrx06i?3=pj8C{~|nn=7<)Xe`3yAv{v`*_~F8p`EFgz(w?TbyBNTkA>H{{{N^^F zBWd!AxZ_T?-uCS<MEVoRvOY$lgJGRjY1Ex0V2I1r2iT*BA3b)CFmO}wfcE@tSZoL5 zcKg6@o%dnJTlpOB3%H(OGkm0Rx{~JYzTI#A)HmA=d`v#lV_%7){&4XDW0Kff8O=MO zQza4L;M5m*h|Zk;;1Jc_KW^e~bDThBOtKy@U&vSDtrolgo2udbZTN-dZ9}A=brdv$ z>diXC7ZQMF3_~%9694!)u0Wxfug}dBR<6>WT>0!ggy&4c?g&PQWSbBO_gtXk&mThv z+t}N|f`NrDKhA~M(o0|bNm8*5w&&$>O(WHYt*HrY7w^*EaxAiTF|9o5ORDe+&}$?b zKh(c7FMtnvS<2TFO0$E<M9cGJdj*)V|9Y~9)6C?Qv1J*HUaSbdSX(oGl02M0zsZ3S z)Y{KLx`~P}&~sh3ZA*Fu{LZCQ*h*cPsu!U9P(d|)WaoVR#e6V{cx<Xj5K&F(bNtJ! z6JD#%MkkC16O#RTnVQqRo8q_>#x6Ytc?-<Cq5-$Jn89zVTK>5Z{CEee)~c()iDkI* zUt6Uv)P5mV@@c~4ZSj42Bt!!DN(V^}DObBO=Hn4g%)cf1NLm68#2sK?E<c`=T<*^Z za&&!NLV4tJeQ-&vY$Mh>yB_72s4(l^-CSlok|aqnLN0erH>u?9_jCqqXC6$-hBL`F zADlO+co{@QS8)pHDin+F##Rq1h2N?RZj-Ht9eBIsEUtY&m&o!kOLghFR}V)vqG;*Y zp^SMu_t?XGBA^b!-6?28CCztiDH%%o!Y<)~IuCfJ5Af<qHh;lJXWyjh7I(u53b_?S z!x*k|Z&_HpD^ru|LL_chhiiIkW&ie%qmCHqMwk#tVXaALSk}W{TrA^dNnuCb+vUcq z14~CAGET(!3b^_SuAF<{at%xm-m1XIjU+WXrtSzn`}N432dj$+chZW+_h646d-rT) z!tmAa*#)7X8x)i+%`7-%b0P~ILqpa?+#!H>Xx4|0<Mw&HRSlcmMn#@;N;Z3@SAa8? zyh7C%5Wkh$B(sysS-}q&NhNpKGHEXq==?NV^qiTM@{&?6)2?ZEY8<w@q8W%_Zb_Jc z4gN3#Hh=;{a@dbr=i6D1`*Ul8CvV?eiTKEaVB#UEhQ<m#tO_{NrE>6cjByRzqwJ&u znmSqcW|>Wdg05V8CmWRbnA%ciNgIv2D~)SSHhTv+WP#@o8uMJybt6=27Vsv>BXkU{ z_$U3%+Z4|VG&R6)mg$ryW<q#eL!iC09L596m*nz^0{^t{N%`B|dvL;~e&3%#@2u;p zQ$8GLXU>|?vr?-j@2<y42xre{b}SqXU1p8{bcw=4lYAU^*Pm;pb79ON?wp&E-0AWw zj=xd;=wuHtk_kRcqOBr5m%qWSwAX<Q7?P)yt%w@@9H-`si8djbLpTjTV!lY_3e+8X z1%U9)k%dF~U(A|@a0_CF9Ds7~`KZS|paqfqk$PJTjim>vQI&q1rmmM1`^fjk`ngdc z{(>+U9BNzt#WSy?Sv$&O=4MdXua}6~x#LP;&xME9bD*oaMf4N;=V)-)Nwq2_TT>oM zm@B==Zh7p&_EZ>#vN(Vs4@Xf1k**Kt3k)<rhXa77@u0+Fdlt%?dav+cO1AER*`>$4 zr*kDaCbdbyTP7u(14%WZ1h3Q!X1_lEsDfh7;cDuZr)sh2YwP{YJurA!ZPJo-n~XN) zWJ8McYJ|U-`Kvs;!;Gn;-#g02unUEE-64wAzcZ$ENwPyDyrT!u_yEonCaND$t>!uI zg1h;Wt?mORMq-2Rqk;RHG44r+J?BfJ)NMQv-M%KChBz{+)xMS+ULg9yoZNC<XknrY zDbw#%H0yU`eZ_nRppL9f{hfz79qS0GUMhp_T4+FWI9J(jj2D&U`3eZ8%G~<gWFyI8 z?9zH0CVKdQd8m#rCa2cVY<8lUzt|*fB^6W~B^@Nm^m_%Vf-ykc`LMYnLalSe3H!(K zD0=b)A&l=C?Kj?IEi#trI_Gv<C!NdG^9{`^&a{v0wV8w&{T~?(*hn3F9aOf@KP&?A zgz+2W=72p4@7EkYR0+K!7k`p27x?obNup^+^M?c)w-ib70E2`hlAR+uQN*9TbK%&{ zc34t!Ww@RTsvujcMl);I6FgNup_gmpMeT!C+*uR#Ir(%bGCz_r@vt#pyk$w2cUI~O zvEk28ia(NZ{n02#;@!J^fhfGcm9v$}HeE01V=i<PyCGBFw<l*#CHL63ljOmR)PY6^ zS2p)#z-db^u8~R?TwdiQApR~=pSg|$CgMyW@KDdCYMCalL`O$=MFFmsd}S0Z%>M%R z7axRUfRxdGQ!klk!JB<42M;J4g}k$hlJYKND{4J9R%blLlKB;oXh?NN9OK%%@#EgB zWUEMjM+u>cbFZb*VXuF#xOCUqCiFZY{i{cjzRv!|ikxGd7GCTKo&)1{mI2_!g*G&Y zU#OrV#psYzf}o1V{enn=4X&iC3j$|Mt~1ZaX(Sg1cM;o33R8%<rPn_<UVWe>p<@1w zw?KpRe1)z%bu#n$QMlcjdUmWYp{%afhC#z;_b|rOrBV&cSQ8@~>a&vJR_7^@@Yo{^ z!FKP!W34}ruA3heS!QD>O)po4RvpzP%J?w$5_x3FKk|QHV!iLi68Q11Qi#BFK1~`; z>&Z!Xe~=Qa&g^8-_J(bC>!oa|k(6KIjm`>n(0H6E|L+jcO@=?IwjrX$KrP*}kQ8pv zRyfzRx0@GpIH#H;`vKkr;lL2Z+iY^%B|j7?n{LLP?qa{tH&nOe-5t^T!)bdQKw%C_ zv^}ti`X@Y$cRkEq?&a46$zv_c$Wf~6_ypqw=CNyns-Jv>N76KWXWx?_R*Gu80@m5C z?FXW*a?s|O3!3Ix$dEHd9!-dGvf8q59_HqQgH}_lov5&%ldcrdLdE<K!pNPB`8tPR zT)tR=Ad1xW%d2wZASW8vvPbqP98aP>7GTTFDXI>z$2Ek)dFe{%58NWBkIbjmT70bl zZBj<{52h{#6x1e(Ql_a)K67ZD>k*C;U)^`N!JOn69%uW|`5XdCz`}{!y=KFaeJc!Q zFdY7?c8687sey~MAi0SauNtquQj=~z1HIAFE8uq2INCwy(!FIuzNtCBhv-YNCJi(7 z&i-Ygue5;rNs+LBmZykChJf~*iLG+4o1aO&0jz@e5)7#Wkqa<0j7|MLxQ*_tr(mtJ z#LJ$TO=fTwGp2zZ7lYbs{nu`@SJg3UYoJf*nv`)edU%WpG{ai^&0Y9OIj2P=4i)(m z8paxPbLhj(6Mg9Q2aG>5mWCx_8*)}lUz%Dle`dFZTW2FtYq7r>g1<l%>T_%v|MsKt z@#A8hK-|)&aw2O<U`+>82NV(SZZeN~&e0$9*+SZ;BDp@E@I0>5C$ny_GH6K>xOx+4 z@0R4Mxb*ejf8cDd@v|8Ir?aFy;T)(1{<adZ=tdk8LOK*<0zi~LVXOv!pa>ooA{Sp} zdOyAg@^m{nz8+8zL9(hMYc;mt@R3xSxtg6xHIJG*p%#+))<gU?FGvs`38`ev(X(I- zY=h-&qW<L|A6F^ggv15(qx2)!c1yiK)`^+nERX``+Ntx2L(>fcj>{7#!vfCn)|C3K zf;>7%PzF7SWbJLXvX6wnrKkXN&Rk<@e+Y`%nlj$IhNsw(e69Y}R_pl|l;NEDeok2z ztaSo^Q4aRtp1P4r4kC}4*iub<q1O+|@jWTq#Ed^A&CPmFe@V<JVp&4{>bLh3l*O5} zt`Np16UN{V&FpK@!Bo&U(tm9?bV=~*l(OH~OQQ^m{dNVvKA+MO{IMv9ph{%A@KHYA zm`$(^^W+uaPKR`jnC^zXP#?xNm>U3AjUyeyapU{~BMzOv{^u?Y96<ZP)f2iAVVZt( z1I;Pml&fNHC-yo}ET634sM8iNueyIb9RAgqSYfpD?rqj_^B;_h{FUG^&($)TqOSyS zq-`FU;#sXHKGG-F0nHH=%hkoSZ&hHfD<L~q6&xT4{-#IBQ|rQ}*wu$y$&Hrg{U=G+ zd1XJtMacd;xXYF2`(`Ly9y$3)hZ}FI(Xr9~_68N4d2Up5X%x%c2M)*nd=ycNtMSc4 z$WxuKYSCDut<l-qt4TwmjE;i67zHPArbsXSg-dPcWu7r>b!BvMg>zH^e7Uy#k~mvg zR&?mf`1TiCg<ZDC<kO{gRi)<;dFh3E^?)>C{Mms_xSXGwI&V$5e5Q7qCJsAW6uUCR zGKuhvj!S<>@tW1gmzxt!yRJ<MAtC=iNWV7Q-6SWk2{<P(K?%2Hz8N)B(+XU)60w94 z8n7a;CBp%I9zUm#PgsE7xR5OeB|@nQK48v+zi%B{McE3w&IlT2KI*_vAi+@Q;DfoK zb9s0QnhZ7&*OV%Pgye?H?81HeK$GA;>O|+Z-(xc`_V=7%O^}<<oM4QX!@daqmCwhG z&F0MgBr|c$JgE*gvn}F~u?X{a7tfRIvpZT*uaP%NCp0Os8PYIR1}eceG4gW*LYJx) zHa1WAd7>Xe4WoP<rP0pzPei4fy4%*|bA;}%O4YQ|p^0&4NWrwO)`199?`UhxD*zRN z7DRtVO3#fjfno(wD>4NIUF)+$hM#*xIU26(oBmV^tnb0QAvJ1sy-cL_=ut%<r+vTS zks-+=fQTOWg#M9)cjk&O*>5Cr+5V-=h#2{cn4Hloa9_77;}!6xC^%ve{x@)%Vu{^_ zry;QU+WG1H1OcFYms6CckJa5U>OE*<E27v1siuSXJY$U4%ykc!Z$%{`%?r65FcOl) zopnEuW~t(g{H#;1WI36|rk$0{fHcn_xp8D2o#fKwc-fEJN-&|&QvmpEdQr%hFWpFz z#K*j^M19x?v`NgRawJt#0e$ItvSdE)9SUIBK$KwxqNY3D#j54iM31U8231z-1c?j6 z`uK0ZIKwm>`?)s~nY9;T)LE&G0~3vO@PUcE11<;()2-w`UP$7Vr<~E%B?BUB5JL=! zKT9~C=b0CFPge>BdEAtE+CtV8YMo)RQ>a1#WMcCKFPM|QK8N5Zh6~A!+q3@i8+@&u zb?ZlT;fDn|BADSkSid>e<xXE8OHPilD=$LlnPO?rxpVv4IIa);SQ=Y!7PJvzLl<YL zf;YSJ{+!tXC)O3htR1zI($0QpOT+rZ(Zkae{Yb{m(j@Cnlh@_<!jy-D1H=3#Bv;Wg z4N9Q%VK*bbODjTReD0I6A!E7`@=Hklk!=x}DJbJKnWHyvD3+Y*tK^{jwvVSLc&-Ce z&{SX(U3{8te)t>R`Sp7d+#KVrDlFzBdZ$gfkLt|+KR6ITItJuDVO((K=L`cIkLY^) zTP@mUU3l?UVISGMP;wGyD9*-yng5piItD+j6~4kUO}FdTTh^{+uy#~61Ak0<*nFP) zyNW0Dm`7j;am;KmPTHL&(tDO{xDR6r-9ys=BHII#N(i?#$=dY_m{jv8Pb-#<W&b?$ z+3{dle%Xx=iaH$12NSM}P{oP}8Z?MZ{MuKwtu!|QS;l5!UX;)>6)jzD-K&gQnJuOT zQu6S13BFwgch<5nQ^)akVFfdsct#uU%ZuYt3N#}g7HzI_K$kmY8IB8C_4T#4cz9-v z#G!m=dy7^>H?ZT+amAHFEOfls)a*UzYrqx|we0ETLx;I0hZ(X_7>{yd=|U>6nek)D zF{~tOY>cCqhc5Fy*!D!)`n`YzfukYgMKIZdVyu=jWu*GXZjz>mjA~1w^fA@wK=iGu zbxIq%3}-SH<EA8&3=5xNjL&{H)&WvOLjF%dQ%!j>xXHj}wY31w_nR1)qPA>{rtdgb zq!%gmpss>K|F5IHkKcy(+ge>gO^G3_)yFUU&x|wW<$fD)&m5ORl*<lzlPqC|WE^f) z$Zw()rZakt4lf&8H;FTpZYW~6C9N$y#j(x;LS`CE_NH^Gs;MsI5aUwS0J&lG{)(w| z*|4n`$U_}skr*1LaiAwJ_h+)Ehd)oawD@Oxc~sdxqEI(c6o<Lj8SI9mxUBX);J_lU zIoBVB?(Z(>=&3T5TOYR4x2wm97FymJr_gI2ec4Ady==nSD6E^&ocUr=K>_D_AH^;d zqI`$4=kfv5O8R~9+{`1-bCJ$S)SlB@5P)%<tHR_!U4o#{@|H}a+B~sc!P^rhnJwRS z6?pzT?jXjpAzq)ssb&4=rrFC)*Co#{Dj&vZFxQy2mOhQ<g7#bSHVR3s=vxV-O{;X* z>VcPbaL3c-TL8J*D*){U*NWF9z1$)v0L1h)BI1QqPV^Jr&18u{3YCk}fD?iUU_v?K zB`ea@N<AheA;~&EI#zv0^a>g-8MP8eqA;Q=@bvOjTRQM=Qu2&%LD&W#($$FX!cghG zvk)v{8RI+KGCnmTtw?Yet%HbS-s@xNbLFmB&$C*j8asAa5Ni%RVq&C3H$Uy)@V6%h zR-XlD?8@P<&R#S5o~|gLR5dtSqg-R!rS9pqBrAip<B?+;FdpqEwiy`vTU(J?Qkb*# zufJ{?72k+XY=t4(R^~&3D_Q1M+M2*d_oJD{Z$<k5gnU6#4$NFv+vu3OE?M-J5#%>( z82UbI6ulk80~q(Wop`jqrfeec{z;=iM@Tb>GIn9G7h%jizpv|>Z0xf6#y+P-fl=E3 znCIf@8{C@lD*$ui%#T4ECad($X5VvIQz3VG%t-(SRj_Bc3F&V0;<Amb34OKxl*>yW zzJGGS-VpSI!0E=lD{5fLW5^Ojf>Lj~=`KiXXq>0nev^}@Q)>ra)nQLkBIxA17@VNE z@EH55_455eXfumb7ovl~y?X4S8FPChoL8M!Or+-746dLGQB2%3l8qXNuMr;-=rp{n zD$SHsTq7h(jI$i=u&Qfxry<U5s!J%2@$`2Dp`jFEvPso^Tq2bh`v6Zg8+NX@IGe3` zyl~oFi$pN+R3AS15WPQjgz#f%*7-ZPdVHUU(NCj$eRi@%h`j5=c~^Nm!z)02>RQG} zegI2H`<IKw*TowFAD@H%p{tRfT%=rc2V-f-8-BdYuDr)<_1Z0G+f&QWEvT;6lD#pK zv_o~7W9eUiXWSJS@Mndp;XT|2U6Jbd%qgLot3_Fx>fhb^jJ{~x&`2;I36+ic4mgpI zxS2DzzQs);@b#$DICJ{39WUP2nEEj7Bdlrq5oLfX6fMl{t>`i<@&Ilud6)|^8Pk;? zh9v_c2iqky>prm9kqB@gl56ihTN{99SD;W42`fkw==#I=LUd>&2;3y7>vDRV%&)sl zFYZx|)tT{zdJraB!SK2abe438C0pjSsVU;rCTWk6NG9}l5<|GD(oHk$xt<WcC;vh^ zSY5k*Rpp9;ZyY1L4<D73=X)EFw6JvEGa(7TQSHZWU*VEYeiiT=TNA9r>|-yibU)i% z^9mViq;{{m9_4Ihk&L#c?~IdU(OZ2GlZ9WKROc0(Q0aHP<RqS7I)P5MJ52^-*zd=^ zShub#J2rtU>>5i_gJV{uw`D{K7_P=@EDHw;ve2kR<gI=vo|}5|JL?wHc&b`_9&(c? zGc<Ym^`6~_>k=1f7la=t&XMFjsiSa7ap?RYHc7=6P<y%?A?}WHI_Q)DaS!<0>S;b1 z&$D&RR4_*Nr^sM0i9e|OCvn`}=B|VW^`y7ZFF%YM&&c0xW{HB@v_H#R$O4<?B_G~x zU02wn>yr~%-Dn9n=ZhEX>+=3!$$17JzRa+$`?Jf7c9Jrj6cu=bCa=9BStRGVtjjzi zsFns}dyn4oZ*d9%+H>50>FT#1U#FwHnPiy;^Md<px`!nb_y$&Jzk$dSM<PMuDOGAc zN^xTu-VKf5n9BY^3J-sS3n2t&rMt8q?rEX+=<nsD+&^i&%2H^EtD{@oX(LoEeChSa zoX-miGYZNaaBdnxHQ6Q`L?_4+DiOV&gw82uly+D9SZu&1V+g%=&9pPFK1iQ)@O~8U zv&>j?C#&H-D`a8nv%Ve4EE3LO)H@vbP22Fh-qvczzI-Hb7wzY+{Fa?-rU0h;wUAR! z(nJ1G$)9LzTgtME@eGP3%1p7J8aA{=D~l5q_^2ekuYhybaF;1o?YLIpo2G2SKkU4> z6I|&1$@GmL6;dss4!>a?+oN_KhmlGMZY$H>%?=I~ye7~NxF7OuR!u4uVwo(b+<;qa z0@AoNu?4G=e()ncLPrfpm9|%ZB05<4-fwSwaXoM^1S;#Pgm2nz`Ydqz0Ef^cj_J*# zpV7<0X13BPWMuH{P$hbQ8&60QOWpr&bFSRnMGYTQ*8pFKSAd}5^I)O@$SNlIt81cu z0@_=S2{^7mmvW1DXAKX*l|3iVmHG^rSCOFpa2<4VWJ_1A-yJro3rUK0-(-ILUL^?y z?=;dY0gi7&v}Whp<hc|G*2KzyixMUm>&q|~tgP4(ux)7M-j_P#@mmxw;x)f(Y8t01 zbKPlzA-EAiHfSdYQWM^@W7e`sJ7&K!zPD6n5LgtDUp!hylwsT?_@<DmLm|tM=2}5H zv?`K7v?9b5jZD%x_!r%v#{d@YE)KGeBeoaGr^tRaHHIFvx5z@JGgP1H_NGI+VRmt4 zua+HB4RDmYYjmW54Z)V%Lb&fP?=K&S{v3G&-PeUnIJq%1y{jJ=6*eY)DgF8S5TXE7 z4=DRjYz6v|<sml*yU8W#HzFqQr3Dfq==Z9h4!soW>t>K1;Aux+0hyQYPVf9sUSJE{ zED7o&G^3T|<+$+r9P0l10IG2U&G`jFa?}7E#V@M^Ouq=$lZVaLhZ-Femjhzs@4|@T z($9q}byK^?&LNigjgP?9<~t}R4ij;-G#MD-%hk4u-SVSRYgKDGN`8m~o4mvb1|+5` z|D!bg`;WRJcF@Wa@%l3{mGM=1rS7-2UjB-fAeqA-@BGk;pvdLc;xmG@wVSQi`)@w5 z!)^(eH&PHn;+MNlP@-nC>`Yzph;{9+CQ@dmZ7k5#&&aa-Iqtm8TfAfY0#1JM=8dEU zk9gi!fR%hl5`!~gW0?gR!LKkL@CTN<r4ZmV+Hl-Zbf<TRl5c%Rv78G+o?rKSgvfk? zo)x4^bH1$<07J?ZK_zLWZ6p4LN!&+AJy+)V!=OTGH(&%)7xrUu0n!CdJuG88yTPe& zwYwqOD}dt^i!<aJ>AZMJxh|Ag8~Wy!{2av*^UEcf!*OR}`SjxG363CER*C|21`0hr z1*;HM#3{hE{~9TcUZp*!y8=z#W}CSdc{o_Vm&(!5zWZ)$`Sg%AUbeWja-goLt<l5W z*SoNU^I3)sIH?Yer{r}N<m4pvo1&$r66nGnwt^G<9I(qC$yT2W<^&bVVy(GT)<@K* zHz}xYYYbMFF<f6@j_P2{WzJ5bH_`^zdgoES%K8gUr;pQd!!5?m9A=7E$d>1^H?y!0 z^xkJ^?TX^OOYgFVJqmmOG8_dWtGAX3AFc&g>ZYvZz1zNJ@py)LI^^vkWBa9O9Z->N zRc5EfIQTuOW^3X{2-!5<^@RSYmz`D@LK~K4?a)mH;(7?2JNshuV@*+MmR(+8pbi(L z?%h*_O7+PCbd6bA=^1+6{6kbMVli$7Ws=Nd&xbegGVLJ^uFt}TQium+c(qd}g@HQf z=#gdp3v8mq6Fdzn0GzFAu8+j0=nHZrsb(2vR>>$!Nir$k2}tuM9zw14#)m{Jt9hlm ztAhtM%fr(d#T-d|hY>TjyFW#ySBEbsc*Uu{4b1F|kV-yL<4<*m7xftD5fa>2Yj;-1 zPr$R?cW_+gX{MfgQ`-vO)^d$Le9xDi_TIq6F?J%^Vt#<4fi`vpaW^NjS~>SwIc7)U znb5Z#d~qAku{8SQH+~wsvbC2dYn(m~A-_n`!PVZ0z6V#X;$>{7u9#BQrHuf)51g(9 ztjC!t8ZF6(<Hr+KYVufMfcNQ6(XRki=MI2fCPwJZ*NwKartP5G!@Ag~vhQ&R?li;q zmXwVMUreQhN&>Runc_JkWNhxCeVC;+C7pNvHjT=OBI==+&=?cetuMW1J#$6mYMkK> z`7y+Mo{glWD;DXK!#vz%MC=u?-hAH;Tg&Q=gUu2dJsjc_5)RDN9m<$}o3bHEEw)9- zF}5wQG7;<m=ysfeky&d?Yu4qSV5bUonPS^85DyNBR4A$cc@=Z%&nniuORFH0`mch- z(zn$q#Ozh;I9m&0n{A-4wx+2Yd~Bsnw>?!j{)wk638+D<p#5B?9w;PDNS=Wq$gVTQ zbn_)s#{T0Uh30YfjsliOB8cuNaF<&k_f~D&H_>k+IXM4ZKb&GFB2LmgP-uDM=AN~R zY4KUO&|e6tTi^Ul-~Yt>%g)B^b&!`36MI>m;wylp2Vmlg^knT{9}4NCKFz|JX6=>5 zwnXAJ;{%*OTPtsphvN79eo&d-4r8Vn6R$|XAjj-Zw?kSZ+#@YbsMYEcs&f+AWDK}5 zF%ZS<muL4`;(IEFqg;LX^cL6Hon(7}5)u7$g5sIp>}9kGVj@`+pG_w?c;WN=>}gEL z7E6;fUM`jRBEKXG>r-~rs<vVDI`VBf<K+$}@wXbrjf4oyYn;x7hVU=7VV`~&g3F`X z`!H993w$rKyw$Z$tqYd!TnCh)uXQa$tO9SS-?DFn!$t?jW#<_e9qRenvuPx`pw;-5 z!IK!=*sNbwiJq%v`)y#Jjb)57y8YCW7VH<OP5*{0<apsZ4a+REDXeQ#&go^XE%geR zO_BT==0zI#=5CAYN9AGaY6+TYRnfbuAu5z5C5{8YmgNB>`$hlo=0bhjbPpx$C&$X8 zXpv4oRt7(GIJaVm28{`O7IR7yjKJPL*i+dcQoxm4i}blyLzBh+{e9@TYyYU9x>oQJ zgkO@cfszkNLmxrAiQ*fGNo_oXJH)N1B4{Y)*l|!#fnpEFu_{>aW2I{6eh*rzcJ$j& zB`Ky;BPZTb*ZHP~nDpmuBU$JwY#2v{0)V5NqS$Wl%|$Cfit-aglB_pscEv)S<1iHk zRT||kM2yU*4DM16c_)53D%(f$T%D99O{m%a_zh*fsu8RFE)`j)>M>Bomh6Ifg@s<O z*M`u<zHQBa9quj_0O^>?1_Q&jYFV{3K1)KdKEf`^tcaXc4C%NI9;db%SBSYWK(wXo zWUXHT<ZnaZ&4YLkL{1#kPL0BtB_Hi@;toaUz)UxWPTNh7!$K%f^S-e#?@@54Ej45G zW1;?!3zh_6kx+>pqolBs#?jL^&8v812SPQ&<HuwRcOa?IJFif5_i=7%54?x)*ke0? zZnb6|eDPfoAsBO-H+c4$fnip%8J{{}t2VT+sEf3e?2YIpd6^3rAyu68P=0O+)%SnW znFw&jxyeo0fNRc#X%9{_e^POdulZ}IBG~p}tJ4Q38!|oigpMiwH-E}97ipS~wR;~5 z9ys59ZgGj_yRb!sF0JyIpuMWBJia=tpn~WxFKe6G9s#3;4d9}GKIO%E&Y}1ICY|Y* zfUfKG<N|kdf#gyUYixPUw6sV{f)_V2mzVMn=b1(cd?}*mxk!9TzTH<Fd{CSazj)et znuqt5XffVwTHlhN;!N|CaF3`2VfhuPx11+6^B?m^RMXxX!m@%+W9T)|T<;t<br{7> zs!;t#Bplw6e|eO8D)xgT79=&+pR#cupAZ~|rcH*U59M0gn_6t=IYu}<2X~-9wfE!L z@KajezXF)HVP;<L`N#|K46{27&TRdSxm!#0<4347vLkq&p9E)^1r;~Y$(1#kym=g_ zKQMCbOi@JN;$TL1&U)m{oPg#Ra<fjCnj<@aiBJCJOJj(``%;a+*)p?rBqT6uS)A?y zl=`ji;`Vxee`rg3REyXDwvG{Nl*G5C`U)_VBJuQhI@Z|Fy|a6nAE`Na7B(_8!f%Mi z#<<al*!J{PV|u`AHwu=a(=sLJJ~YFoe+U`}k*IlN;8l1EgR88I#e+>zgOV5a@|+3( zSfU+icO@U^A=iyma45Sa42stup!u^3-(cv>gZwu1u{FQhIeQHPUoJlC_^pWnuS<!J z7k+sOaQV}Rt;kcs|1!G|-6Da4$4|;-5V#x0rEmk#Uc3zy?wEn4u8Wf?rf_lLGcy_) zE<TWYfYYr^qx*H|Q(<*Mn@E%0Bhx_eSS-KKd$mY}afho|f8O{bIL(fx4Sz<LH;S&( zNZJwR{>L)k5QQ&d!$f$U_8n5l^{*C3(f1aoM+RyErUq~xF_^)!(QVM_8-uUD4idEe zu^J}HfTPJ1Lub0n8k%*ukn&C=KpOA#E7KbmlD>M#(mM23*g#hr)Ew4Y*hg!fSFE$0 zEAUK0s)nwrxtvr7mK}tD#e&Q`E{fg4rPpSjtnOXy%OYCgk9;@*d$?9V{pt-7@EJN$ zaMH!^l>$FUjY&|?a6W$Vajmn`zAz(CsbuLVuRp*$qg~51jWBMeC7)}Vz+Xvup+Bh3 z<&0?`(M%AH8x)oYF}>gbvJg+;^|9Lo-%t=oWnT@)KJ1pc@5#uJV_ALq6r@G?^XJmH zcN+m@dGLOjmSR2YV`G-Q$=c9K_&ewT=@IF1wXg;HmUI|V)0DHo*ykmgIfG0dNnQC_ zQ%V&Z65gJOZ|(a!OkauMBhhD?;Eu+KnbtE=jI(-OZ~KIK>O?-FV`Gm~o00zZ_pOJ# z0&Lw;RqB+>-Tf3N&02|NTT~|#0Z4*W=?GM=LZxlOh-Y&-&_5~wMI7z;^IF>4uX|Z` zo5!@_8b|#UoJ5$wevU(j`*gM(R{cK$@)-^0Pjzqh+>^r1C)@<*rqu)SuRqh`o;dGg zmM4h$dsGlcPT}A4uAAab<dS%X`ugJ7#W0k|YK{O467Y}t1CP$R3rQvrGtDby&kS2T zeg6PDI)Ty8rCn;;9fXm2O3*Vv%`B>cfWcf6dFp>k^jFcZJQ488wA)pLc#p(5d%|W! zXe|fbKuPC!Q}y;07lAZ5?ry9l)@LcBXcnVT)V(B;{$-Co_+C8$uQ~D8igj&!#Fv`A z{F24?rzRv;$|?>ORE`b?I#31Zbk@+c$*ylA%#wmIq%bN!gb|U+>yE;(W4xB;-tmNo z&)w$&rx_!t{J)i4@b;nop%dvEmBEc?ZT6G7<_YnEll|7{e+tjoY;Ve3MdVFyAxYxL z2eV_-uTGwn0e@JTCAwK;g&sN4W>UW^432pndCyR4W!2=F7CW~~*jJA)P>jj6dMvAl zU%-J=CXuM!X;4LLZ6xn*?;aIHJ0^0hqp2Nv9@Uv6G;*{THli614Uov+k>m8FGU00r zl`E%1aRlH3V3CA~-s;>Q{RljFt?wO)Y_-cxGI5Wy*+Qy4$Si+Wtlt3JL36Jq<e`P0 zoQ-oc6Opw6Y;@<IKM`7g5^oykQ?R~YEZyB{@W`viMsf)m>(iwGb9WML{n{Q!-Xqqw zJSh@Fx~8W8056klVozx$AqGDJO>$mznIcDZanxrO*+B@j@I|PSR*mnjT5<<0=!0sH zrb~WRLNUopLHpnyL-%7nz1#dh`t>cIw|#0PMU+c#A<Ns$f=HX{hmXW_Rc{eQan7SF zHdtr)NH{C+{{YvdvbK`yL6&g60w)EJ_)rH`KAraIVUor*9(*Y>?q9f_7=OT9kD(Q_ zr|9rop!2_fCvyCcz*Kq)t%jc)IV>#X-ry2(44*83dgF%r*1YOrnd5A3Mj(;U(@0I4 zdKJu3JeD^^Esfq0h#%_T_*{KImle?XW@%!3jSBaRi*3(u&T_q30q#GDdlQP{3uIvO z4RjFCHTIho^|O(yX+>DKcZhw~_s2u*eFav`Tb*`jrblxX^`sZ}qii<=B|qnzkG!9O z{RpFVYjOwCOa_!10Cg=lG-iMuK<iD-C_IV)u3M8yznYDknrUh-1cj-ksv`8pdH|Te ztw7PnGq4mVsYACvUth+W(o{_)Ca<{4w_0tyq?V30KA>zrnB(-Uo2?l}OfouqINU!m z{uQ>*?@>IS^&G39?s9Y4T|^6cWzcnK&f)r12A2mF*-FYzNco3;<MFCjDHPfBQ6&EW zd}RK8e_B>(XDHH|jix=#Y~1OV&z~)x6aN5xuk=68vTn4?l_bJaasL2J&p(momBPhY zWDWwevJi5TFW!v$k8e>`Z%(Oqr`&&OUCFi?)C-9Y;*kU;h-1mg+ku|GoYSMWo?DR# zMpo+EhBkrJns%$CYI>9r!KUf=v)Y$-+^Rqfe~F2}?s)C_)U>xL8CQNUhH&vurbBZN zMH0El1Au)2`eL$x((fey0FO(HWo~mE!Igh8TY7(hE@qiwp7&2%q6-^;JI#;**W`~S zkF`ZUo8jnK3#~^`ykz6cwtzx_k9RpAl`Gr}Q&^ok8;wB7V}{x_wYGAM!Xicswg*$r zJ;|;_+t?P#)Y-BQc0k<zWLKo>mosU$aqIRc?YbSzOKo*&DrCan^Ug)+Rk<O!&ukDY zlh!mnJ**d4(A+kaE9_*HlJ>G5e7871@D|`O_XGe9h`e2U;ai(~EjeMAOt^wJmJ5~h zBD)P5^6Gy9$4nk+t)OT=H9l{H=l;po&o820OZ&M`e<D-Y{l@3suyu=LdEvb_<wof( z9jzbAVE9w>r%$Vo!m*94lSr~g3c2KimBAfPx2*tfct1(Hu=tIo*=pAFTD`U6$vkr* zQi_Lh$UU$r`qrawq~Bl5X2NY&?pJwk2O>ShlB@ahYoU|I8r%2@!PMU3drO43GrFme z#L7rQ#BM8*(3-;5Y%T7r&c79=+l_)tiy@3F9+KmzL)RYulmUl%YbL5R`G|9OBzqb) zT(jWeSbaws_N(_Ag{6wy=rGw@-^CM`m8UE~kmGj3q!0idd*Y#%Su~4gxSfgCZxf95 zw}}4$CL{6{ogKq1n@w=5ER1}#EHFs#k~yFY_ZqH;bV|>sUR$E!6x-Ye7#%RKync0h z(%VdU4c(>P%+cCLAMDe_6L~F#%LY7T{*}x$@C8x!DE)r>e~oUdMHhxI-|XrHhTc2| zJpJa!Uep29>DrZ-h`c%WUl7FjfwoC3f9q|D;5z!Rs-8ccVb9>}`)?HKcIme3OuTi9 z-s&HkIg`K9v64aNs(5QqSiaLcM6Kka`G`q7;w`m-^~Oixn)ELM>PNylwaxvE(o3R5 z5^-rFnFLJCHn>0C198t$wCB{9?ggKXx`JrBGWa`8mlr|S{{U8G7%b=RN1sGczmPTJ z@LtN90m>HYa2Z?u<vbs+TIoD?x4L(WF6O_S+(~gW%^kz@=Emo6C-cTVK^4#6!)*=I zCMAha%%>ZH1ZUcS7{b<P0%)4rR_P=^JZ=8~0X&bu{uSA=8itQ8_=YRZcET|nxH%HU zI1&}=%%cG3wmmD8NdCyUM_Dc(1y`og>x15`Y4<bua{e2r!CTNofJvNeJ&&$O=x9JV z+TLpS1<mEJ_JV*snI-bsxc(Awx%SR|1zc@!U(>DzoqZ(EP-WuOViKw^u#g-Naf+YC zwy{ZSn!c8it%c_*%Ahn&{Bbro;Nu6W2fbm(eSZ3UHX`O(Vln{~EO#oO_Ce{KicJk3 zlc8K%OW_$LI(&A`tK1t%MX6;5H2K}wF+3L9qzrzQh4BW_H5Tym#V}imG{p+LPSyfR z2T{}U827CY7~LHj^GDMnd<`}@<8T1MZ0?o67C8R^fKvQGh>asmw}|X?wUDOY;zgPA zzmo&_PzM~!`e?OFh??qIHkiw<P!IN7zu~~G?;TF#Sc^@Jk}PfGw>a+j-2VXh^BT_h zezMErD@YzfER~G+3Drs<EJ+89;B~8hDo8)J9^xrlM!a9ONEv}DT$TXi*n{}f*hE@9 zKWd5WB-^~7GAy2r+<qhV#ckT8R;jiu7C(9M*Xighow1l(&XOqGgUKC7zxDhpdiAj) z%76rvZW!nfaryp)Q$Wp)BIY%|M4$acz{4l|tT2Da@U10h`y66p`}<}#bAP;?Dg0M& z)Pr1t%kN!OGX17_pFC=I`2PU6n0kI|k@ay@Nbvske@E1$(=`}wq5-xXIv$RP?<w{o zu-0FCnPm5-2cl`s4wtKoSmgfzi8ihTwz4teIXeP>@zd-<ttTxUjE)MroDh2&<UBVt zdaZ=o1=EFT36{!2aplYX-1ZIs0N3m*rL??#PfQmRg1UvP3wzWf2XNtE9{9oc9`xe+ z38K(?Q1wtrPY+f}XLTqw0D5qG0Gl+R@+uwF;M|G;s81%EO*Na7QL~x=b2UcKOlGK= zr~&Nt6TLB>qGqH5yoRB7G&58#)D$DOYP^P=%}~f`Fd>zy3EC(i^Jd>O9+1O~pQ$_# z)YOhMP)MiJq-IR|?ynrI_E9~z8$eN=quV(-_pHrw>iYIA5Na0}60<yyCz#~q2JiR^ z-j+7UO3T+Fc|OOr8N9g2I2{RNQqa>l;~er%WmR=@+qVOP4s)8@y43FPZ9miFf_wBM zW#g~!NbVfx4tij)C*Ff^FL>YbrWj=Y<9<|FE*=`x?(|(kS!D@%XLP13%UMY&aT)3l zzi@hkgIBKf*}N&K#i?j4xBeN_!H;C)D#_L0m=27+bJu{w9kX6HAHd(0bRHGGFn`3R z=GIH=9aX%!?NzW<Mn{;ZqPXOP=ni-$lS54A^=rn`rV;3IEP7?iiO@;}rNPe(NXA!@ z(0;X3`)#DNk~@t$#&4K>iy4fO-|ms<E1|p5bicAqV;6|*WlL*@@+ElWTp>6iu%vT< zcqhG9v+&KKk)&;NN|rd+dnjoD_S|-GGv0tD(WSPJ!#b>kPDl>e?gT9%lW<nRZKu<B zez^3j8g-mr8r`ewH$G;wdl74GKH>bcwZD#jdLGNheXC!?x?||tcDLd=u41~98$Iwz z79QNcnu?3hp*h9}0=(Mx?(0yymgeqxC%Bc1JGsdwkR65H=Z5vGo%-*Gue95#o148V z<IIec-^-AZ`8cY#UJkI;8CSzzC(`ap4XbT>#?Ea20Koo2N%U&x^z(6TaU83(DzIXN z3^4RQ)RWt<ogsj2h_NWG)DFPV0_$E7*YsX>T`KC@GtyR!nA_Yq;Qj`maE&L0;f)lR zmgoQg$vYzh`qqz!^`8-GlcX9Q_3UjU1rS2ytcTF2M*Kx}8s4XGG%?$1w+jxifVA>y zcG0RXe}sj=FX~tI#V|On4@r{F?O#xuD|DF}6BD1EgN?mAb?R%X(1+UXXV7%(o0~mi z(oZ(X$m0__ZVeIRsmZ|TdVP8I()5d&1H<Atw-f&WFEBi0pRYByf2ZoQ>N3xxNu<vv z{lZ9PPd9g|-+~T#;)?+mwx`A39FYa5k*w(lh*1dNAMvOiutq@bgO0V#D@-k-G84pM zOmdHv2sqqx(||g1Yte7x)#irR#D8a+9ahMN)Gdc8aGgBV1A=`=t#TeI(*d7ls}l>a z+AU6VzB9>Bs+{B6m93y0#PcG`?Q95<&RSE+{4>ygwPwp$o*Q+vzKt~t5z-0rc6#h@ zyocy<>J3&)V0yRdQmv|YB++2G)_7cLcTwEw&|J6nb?^dPOOgc8IQz0je(U4DFvNci zGs4;nY5q0~sVFx3LN)B9a;~U1DF?VGZY!ID$jvfE1WhEa!BrGwvFre^SxqWW_(o^& z?6+{q;&!zdg$7&7Rt_!8_kN@gU_I#Q2bSxXlIpsx&FqcLu2=)q4A)QN8?rR7311K# z1eslbygzr5`0h2zv;<@fkF9NZhkN)JKxP>++}x+>86V1kCDE*om8JNO>^|(owopI! zgr_<DV+ZrBjY4m<&m4-F+YC`0o}~~jfAQMrZy>n;0E8n$fV_L=XSt9&1tEUqdCy)I zu~=fo{{V`6b^ic?=lKd?R8}LXBDb`ue%EI9+02XcC)9TQM;}nNpY~Xn@7>4$00Bln z(x<mJ_U;`nC*BAkq*%cm_cQ@IlUur6l1-!DMFSPOvt_@xVbn4ooAkl_D+)`PCz<4j zF$Q8nIL1Dmu~+m<!>8(&)5tRx?XC|-L&JWA(-FCRVri1%-9p>kpq@1y6gO4>0D!jT z{{Vp0O4Q|npo0GZO=irRWX0nrt3e?g{R0(0_R!P{)X<r38Cp3N<6^F)GO+3h?_K;_ znm>`^NYiv~1*We8_XmL|@;UVbxvx4_t-lNE%cftEbiQSU%9w6rJsA&wsOy>l?r$MB z*9{nO=s;v~(bV!7eMLs5i#T2=rqQK;Hftm^*-QTbJ?&389_#7bkx;8urb%QqJzA@) zRDjbFU>Z<)6#!~*Jc<CU$CFX9rxVtrY5-#ziK<4Z*iZy*P_;})6%z^uMAZ|DuvVDM zNM%+P8!cI3Oe;VYSt=$<w!))j%_|J1$x%90){dBCqy}V==e0oA{=&7|Dv9Bs3}b5Y z%CSWmcXPE>MoBdWxpfwoZ!Vjsvc24cZQa5jx;w_F)71C+S3wT=BAh^WOCszN{{RvL z*KekMYn-^yopNJs!}X-lBb7G5TZoj9H*P1_(x%d+lT5x#m`HqOUN;$86pS*k?g+@O zIqYPJoT1{hd@W}Pn&VZ!Ky0+|BxOJH(nI$X@jRbkYHT}~;l8r)b-Y?!wjXG<)CrqX zwUPHSLf>*Q*x}S+w`1>Ou{=qkE{}B+TFNeT%cS$H?o?n)AHSmxj5{B~s@_RHrF%8h z`=pv@F3pal*G1u$4PicutfYfVoS7n&47H@#;zb?7=*!%DfklRL1XYbYPq@^s(%Q}= zB(2+^1Gy)l1Ju>{^hw%fMv^o_*fJd84_=x5D)zZA*sPmO(G}vfaf$9&VoQ_n{nhke z&nB3PciM%vg#?ybEP`v-1uiegVcjD19<9{-3grV8aOy~4bDFwsFn(f9D78`iIixbH z#}urygwG>-j>p!l$>hs4l9c7xw@*_~@`>^8G-f!ntO{QMs_0B(<7V+H<tFRQnOq zyX$GRzZ1l>YH2W38<*^1M9|6?usk;GduJS+^Imcz^vznZxt_-0O9SAJqdi3cYu@-C zTlnR^@U83`<*>`TTdvE9hkfv$n0-b^y>hntb>+qCS=-ymCDXRWiAT&&rYq9CK)xUF zzPi8hE4#SVLZ!!_9os;GokL|d@;ds}n7$<2-s&v+rkE|nu$yyxYQe6f2l#`q`H!x7 zKB9q`FD0*mU~79vj_btEyJomwnJmHTsp|fxwQ_d%v%z|okxb&{AIuVG=G~m<HPU#C z!xC7+xAyYKsOd8|?ysQE(to<+sz3WD@Xd2lS-0>X&V&a`;;13j>=VS=bZUZU5$X`A z{{T~Pe~1t6zh7gK+*K=x9`nF<vBV2Vnu%2d{iOpRo+`hFb!O2o-EUzt>6c05UBlVq zKAwbi2eB30X&O1wA!G;bc2Qjm>uHp6JYqIvAbRdlq;??sPzNL8sfYH|_OUi??E+e$ z9Y1!vN&HUZ_|{sH=qdvtk=fkk*pg4FG~o2aSOG};qw=Q&U+#*8Jvd1~69iB0ih3YI zc4c$a1I0kHQ-qWO)lG839XD1*5;H{h7fO0J%0iRxf(Z9PRMF|)9e=jk-)X0ol|1Nw z>!Ndk?nXsbj!cSTE~`|^)k$8ZN2Uj$cwYW}M^A>{-M`{<r606dp7Nmk(S9SR;p%H@ z@WV84U)YRU-LCW>^Uc4B54b<3E6lX(*=%nixwdkXM8TB%*QZ#|Z*~?)il&{cHs#L( z*7OcR^jGKg^b{=w$Q7zU)mg(uBS#{YbtPF(P)BNdwra#!4NnJ=Py<f~kwA#pa%qez zRvemP6af*a+NNPqu%HN9m_<*DX<7iTMKFr6R--FG$O_X6)q=Fbv;kd`m{P2jrjbBg zs>@6(R*KU~Qn1RUO*F@vx3Zd2iv`MtI%$rs6{hT>z*3UkBp7uBdx}Y|;(b0VFDX_8 zkjg;*H$Bg;2Li8br1I#nT+T~K;}}F$9>WwEN2O>O#UYNBfX*;+(xH2N<PpVd7^#gH zwH6uATxn5B$X%z}vhH-5W64F_J*%_weW{HHwH5<`cv*h(;+f^wadD@|Fd@)=M_S6b z(1^*2iS{(C7dg)^k1Dh$vX&OZAs>Z9j2>wW={_XJWxvtx2mH6v;BtNbVf`zQHu*f_ zyPp~lH$?EP{<a=gf8AsLHO|^uH0(BtEFnBSsNd+94%QL|icz*}X;*wxFZW$f1b;5o zv8w61b>EeBr$sfJNs}$3{L2~t0AaI|r_k~}O;2m5EC3QWH?3L``%%l(E@8)`!Vk_1 z{cBn&W{So;IOJrvjO7)0+IsMMikPN5Qf;STF=WzVKX3*70jknzY`=CiVeBiSC_O0( zQD8Y{vs6Dk0e-7Mw~HLczm;^&9(sy}?4o|C2h)ly2S4^$PyDkK@3BC7#w%I$@9sGs z#-V#T)A&OVY5=cc8rfaNb8YfV6K+%JX_DLTk=+PV#GSa{eJWfs95Rr7#XB?sOsuKZ zay>^h<d-#TG}lFbsx#|A4M{7i@NTONa!sY`4#Q8r!m|#sN&GS|xFCK)xg!Z5alZpi zEb;y2IQ0~O_H9NvZY_<?zykW&g}vxrg|YHVKiPG`&-m7IwMXFXc{LqB&bj^M){%J^ zsh(!FJn#PidNcEVH+l-2P_}yu*)83J1?60Hbv%Y2QC68OdbLWe$f}6dG9E=RxnPb> zHI}6#lSoA|709Nr;-_V%6`%+Rrj@G%Q%ceTxmsyjvR0T@fFLPND^?2AO3(#zwHqy3 zDNJPcpbDjFrE1YiLX_+ULbRJI*2+z^fUIMr^6JT2LbMF8vlMNq_ELnP3fpMeR)SLb zbi(CLw1zy@zb=n1kX)tZpGrKUdsW{qjg$q-MjAs1tG-<($^zzmma6N9P)EIFU+60; zlMl+>y(_2LNwSrK=5C{=HP?jvISa`jood$!Du&4bvX$bQZ)T826$UF%r?oJrwH6DM zjC9hNtA#0yl)~jkOw@i~HF1)oD@BGuvYWE3ZKT^pfP-Zl4Nta>w5$bvv=q%)+e@~c zfT+-h7$Y@aT|OrM9jDY*p4wfstQRn((^!A2f6P^BEoYCa5<R)Dn_%>$F$3C*1<q3> z95BK6rQp{~C7MVu$`904NpzUo?qyH4D+S709rU_Js}1$9-;Dgr+1I!==^B*qNv3K4 z0A@ngq!zWCKXx<8g#Q4zPaec)n)8WtyNLOW?)ukB;EVQVmqXOiqJrS=f>s|aQjUi` zf$#M_@k?RuY9XnkJc@|NBr?2HAz340tf#RZYDDTP$Tdpxc&6?8(M2#Dk7`0ajTBG= zN}ozXr#&d5fDozlG~I{NiYNgJA4+LM*il6QG^e#Rr?nJN14<fh!|6p70Gkh`G{$`m z6i@<e_N3YEMHB#R_NCZ;D58KDWiH=pD4+vxwHptm6i^{{A4*Rw`Wh&p17Y-}G5b+P z0~2SpCznMOfI^4Tm}4|iOhXEB(wI>C8YrM+T0S~dO&QNhD4+!L{i!w|Lq!w}LWk0m z%RZD*KnBC;X?CAVD4+l*wL53E6i@=}K8BPb^rDJF6em3?;XSCLm=Y|0)hfg@_kT(# RpbH2+s%0FGD58Kr|Jfm)sf+*s literal 0 HcmV?d00001 diff --git a/html/qconvex.htm b/html/qconvex.htm index cffbc7a..764d0cd 100644 --- a/html/qconvex.htm +++ b/html/qconvex.htm @@ -130,7 +130,7 @@ in 5-d and higher. It disables the following Qhull <a href=qh-quick.htm#options>options</a>: <i>d v H Qbb Qf Qg Qm Qr Qu Qv Qx Qz TR E V Fp Gt Q0,etc</i>. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qdelau_f.htm b/html/qdelau_f.htm index 8a487e0..06dde1e 100644 --- a/html/qdelau_f.htm +++ b/html/qdelau_f.htm @@ -114,7 +114,7 @@ in 4-d and higher. It disables the following Qhull Qm Qr QR Qv Qx TR E V FC Fi Fo Fp FV Q0,etc</i>. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qdelaun.htm b/html/qdelaun.htm index 74150d0..2772f85 100644 --- a/html/qdelaun.htm +++ b/html/qdelaun.htm @@ -7,22 +7,22 @@ <body> <!-- Navigation links --> -<a name="TOP"><b>Up</b></a><b>:</b> +<a name="TOP"><b>Up</b></a><b>:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="#synopsis">sy</a>nopsis -• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs -• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics -• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions +<b>To:</b> <a href="#synopsis">sy</a>nopsis +• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs +• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics +• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions • <a href="#options">op</a>tions <hr> @@ -52,7 +52,7 @@ by O'Rourke [<a href="index.htm#orou94">'94</a>]. </p> <dt><b>Example:</b> rbox r y c G0.1 D2 | qdelaunay <a href="qh-opto.htm#s">s</a> <a href="qh-optf.htm#Fv">Fv</a> <a href="qh-optq.htm#Qt">Qt</a></dt> <dd>Compute the 2-d Delaunay triangulation of a triangle and - a small square. Write a summary and unoriented + a small square. Write a summary and unoriented regions to the console. Produce triangulated output.</dd> <dt> </dt> <dt><b>Example:</b> rbox 10 D2 | qdelaunay <a @@ -72,7 +72,7 @@ the sum of the squares of the coordinates. It scales the height of the paraboloid to improve numeric precision ('<a href=qh-optq.htm#Qbb>Qbb</a>'). It computes the convex hull of the lifted sites, and projects the lower convex hull to -the input. +the input. <p>Each region of the Delaunay triangulation corresponds to a facet of the lower half of the convex hull. @@ -89,35 +89,35 @@ For example, the Delaunay triangulation of a square inside a diamond ('rbox D2 c d G4 | qdelaunay') contains one region for the square. It identifies coincident points. -<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output), -all Delaunay regions will be simplicial (e.g., triangles in 2-d). +<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output), +all Delaunay regions will be simplicial (e.g., triangles in 2-d). Some regions may be degenerate and have zero area. Triangulated output identifies coincident points. -<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input), all Delaunay regions -will be simplicial (e.g., triangles in 2-d). Coincident points will +<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input), all Delaunay regions +will be simplicial (e.g., triangles in 2-d). Coincident points will create small regions since the points are joggled apart. Joggled input is less accurate than triangulated output ('Qt'). See <a href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p> -<p>The output for 3-d Delaunay triangulations may be confusing if the +<p>The output for 3-d Delaunay triangulations may be confusing if the input contains cospherical data. See the FAQ item <a href=qh-faq.htm#extra>Why -are there extra points in a 4-d or higher convex hull?</a> +are there extra points in a 4-d or higher convex hull?</a> Avoid these problems with triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') or joggled input ('<a href="qh-optq.htm#QJn">QJ</a>'). </p> -<p>The 'qdelaunay' program is equivalent to +<p>The 'qdelaunay' program is equivalent to '<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a>' in 2-d to 3-d, and -'<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>' +'<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>' in 4-d and higher. It disables the following Qhull <a href=qh-quick.htm#options>options</a>: <i>d n v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V FC Fi Fo Fp Ft FV Q0,etc</i>. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> @@ -160,20 +160,20 @@ input</a></h3> <blockquote> <p>The input data on <tt>stdin</tt> consists of:</p> <ul> - <li>dimension + <li>dimension <li>number of points</li> <li>point coordinates</li> </ul> <p>Use I/O redirection (e.g., qdelaunay < data.txt), a pipe (e.g., rbox 10 | qdelaunay), -or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qdelaunay TI data.txt). +or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qdelaunay TI data.txt). -<p>For example, this is four cocircular points inside a square. Its Delaunay +<p>For example, this is four cocircular points inside a square. Its Delaunay triangulation contains 8 triangles and one four-sided figure. <p> <blockquote> -<tt>rbox s 4 W0 c G1 D2 > data</tt> +<tt>rbox s 4 W0 c G1 D2 > data</tt> <blockquote><pre> 2 RBOX s 4 W0 c D2 8 @@ -237,23 +237,23 @@ outputs</a></h3> output ('<a href="qh-optq.htm#Qt">Qt</a>') to avoid non-simpicial regions. For the circle-in-square example, eight Delaunay regions are triangular and the ninth has four input sites.</dd> <dt><a href="qh-optf.htm#Fv">Fv</a></dt> - <dd>list input sites for each Delaunay region. The first line is the number of regions. + <dd>list input sites for each Delaunay region. The first line is the number of regions. Each remaining line starts with the number of input sites. The regions are unoriented. For the circle-in-square example, eight Delaunay regions are triangular and the ninth has four input sites.</dd> <dt><a href="qh-optf.htm#Fn">Fn</a></dt> <dd>list neighboring regions for each Delaunay region. The first line is the - number of regions. Each remaining line starts with the number of + number of regions. Each remaining line starts with the number of neighboring regions. Negative indices (e.g., <em>-1</em>) indicate regions outside of the Delaunay triangulation. For the circle-in-square example, the four regions on the square are neighbors to the region-at-infinity.</dd> <dt><a href="qh-optf.htm#FN">FN</a></dt> <dd>list the Delaunay regions for each input site. The first line is the - total number of input sites. Each remaining line starts with the number of + total number of input sites. Each remaining line starts with the number of Delaunay regions. Negative indices (e.g., <em>-1</em>) indicate regions outside of the Delaunay triangulation. - For the circle-in-square example, each point on the circle belongs to four + For the circle-in-square example, each point on the circle belongs to four Delaunay regions. Use '<a href="qh-optq.htm#Qc">Qc</a> FN' to include coincident input sites and deleted vertices. </dd> <dt><a href="qh-optf.htm#Fa">Fa</a></dt> @@ -265,19 +265,19 @@ outputs</a></h3> <dd><b>Input sites</b></dd> <dt><a href="qh-optf.htm#Fc">Fc</a></dt> <dd>list coincident input sites for each Delaunay region. - The first line is the number of regions. The remaining lines start with + The first line is the number of regions. The remaining lines start with the number of coincident sites and deleted vertices. Deleted vertices - indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). + indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). A coincident site is assigned to one Delaunay region. Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'Fc'; the joggle will separate coincident sites.</dd> <dt><a href="qh-optf.htm#FP">FP</a></dt> <dd>print coincident input sites with distance to - nearest site (i.e., vertex). The first line is the + nearest site (i.e., vertex). The first line is the number of coincident sites. Each remaining line starts with the point ID of an input site, followed by the point ID of a coincident point, its region, and distance. Includes deleted vertices which - indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). + indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'FP'; the joggle will separate coincident sites.</dd> <dt><a href="qh-optf.htm#Fx">Fx</a></dt> @@ -394,7 +394,7 @@ for cocircular or cospherical input data. <p>A non-simplicial Delaunay region indicates nearly cocircular or cospherical input sites. To avoid non-simplicial regions either triangulate the output ('<a href="qh-optq.htm#Qt">Qt</a>') or joggle -the input ('<a href="qh-optq.htm#QJn">QJ</a>'). Triangulated output +the input ('<a href="qh-optq.htm#QJn">QJ</a>'). Triangulated output is more accurate than joggled input. Alternatively, use an <a href="qh-impre.htm#exact">exact arithmetic code</a>.</p> @@ -414,12 +414,12 @@ the origin, the facet normals are the Voronoi vertices of the input. The points may be restricted to a hemisphere. [S. Fortune] </p> -<p>The 3-d Delaunay triangulation of regular points on a half -spiral (e.g., 'rbox 100 l | qdelaunay') has quadratic size, while the Delaunay triangulation -of random 3-d points is +<p>The 3-d Delaunay triangulation of regular points on a half +spiral (e.g., 'rbox 100 l | qdelaunay') has quadratic size, while the Delaunay triangulation +of random 3-d points is approximately linear for reasonably sized point sets. -<p>With the <a href="qh-in.htm#library">Qhull library</a>, you +<p>With the <a href="qh-code.htm#library">Qhull library</a>, you can use <tt>qh_findbestfacet</tt> in <tt>poly2.c</tt> to locate the facet that contains a point. You should first lift the point to the paraboloid (i.e., the last coordinate is the sum of the squares @@ -489,7 +489,7 @@ conventions</a>.</p> <pre> qdelaunay- compute the Delaunay triangulation - http://www.qhull.org + http://www.qhull.org input (stdin): first lines: dimension and number of points (or vice-versa). @@ -559,7 +559,7 @@ More formats: #coincident points, #non-simplicial regions #real (2), max outer plane, min vertex FS - sizes: #int (0) - #real(2) tot area, 0 + #real (2), tot area, 0 Fv - count plus vertices for each Delaunay region Fx - extreme points of Delaunay triangulation (on convex hull) @@ -597,18 +597,18 @@ Print options: <p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="#synopsis">sy</a>nopsis -• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs -• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics -• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions +<b>To:</b> <a href="#synopsis">sy</a>nopsis +• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs +• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics +• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions • <a href="#options">op</a>tions <!-- GC common information --> <hr> diff --git a/html/qh-in.htm b/html/qh-code.htm similarity index 65% rename from html/qh-in.htm rename to html/qh-code.htm index e2b5b5e..7051f06 100644 --- a/html/qh-in.htm +++ b/html/qh-code.htm @@ -2,7 +2,7 @@ <html> <head> -<title>Qhull internals</title> +<title>Qhull code</title> <!-- Navigation links --> </head> @@ -14,15 +14,15 @@ href="http://www.qhull.org">Home page for Qhull</a> <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> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="#TOC">Qhull internals</a>: Table of Contents +<b>To:</b> <a href="#TOC">Qhull code</a>: Table of Contents (please wait while loading) <br> <b>Dn:</b> <a href="../src/index.htm">Qhull functions</a>, macros, and data structures @@ -33,20 +33,42 @@ structures <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 internals</h1> +height="100"></a> Qhull code</h1> -<p>This section discusses the internals of Qhull. </p> +<p>This section discusses the code for Qhull. </p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> -<h2><a href="#TOP">»</a><a name="TOC">Qhull internals: Table of +<h2><a href="#TOP">»</a><a name="TOC">Qhull code: Table of Contents </a></h2> <ul> <li><a href="#performance">Performance</a> of Qhull</li> - <li><a href="#library">Calling Qhull</a> from your program + <li><a href="#cpp">Calling Qhull</a> from C++ programs + <ul> + <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">UsingQhullLib</a></li> + </ul> + <li><a href="#library">Calling Qhull</a> from C programs <ul> <li><a href="#constrained">Constrained Delaunay</a> triangulation</li> @@ -183,24 +205,234 @@ is creating new facets in qh_addpoint(), while qh_distplane() remains the most expensive function. </p> +<h2><a href="#TOC">»</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 an external +command. + +<p> +Qhull's C++ interface provides wrapper classes for Qhull and Rbox. 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/qhulllib.h#facetT">facetT</a>. +</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> + +The sample program, +<a href=../cpp/user_eg3.cpp>user_eg3.cpp</a>, duplicates Qhull's facet dump (option 'f'). + +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. Please send these extensions +to bradb@shore.net for incorporation into Qhull. +</p> +<p> +With care, you may create multiple Qhull instances, but only one instance may be active at time. +The Qhull library refers to Qhull's data structures through a global pointer <code>qh_qh</code> that +points to <a href="#qh-cpp">QhullQh</a>. The class <a href="#usingqhull-cpp">UsingQhullLib</a> checks +that qh_qh is correct. The QhullQh functions <code>startQhullAccess()</code> and <code>stopQhullAccess()</code> acquire and release the +<code>qh_qh</code> pointer. +</p> + +<h3><a href="#TOC">»</a><a name="coordinate-cpp">CoordinateIterator</a></h3> +<p> +A CoordinateIterator or ConstCoordinateIterator [RboxPoints.cpp] is a <code>std::vector<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">»</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">»</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 qhulllib.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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</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">»</a><a name="usingqhull-cpp">UsingQhullLib</a></h3> + +<p> +UsingQhullLib 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> + <h2><a href="#TOC">»</a><a name="library">Calling Qhull from -your program</a></h2> +C programs</a></h2> -<p><b>Warning:</b> Qhull was not designed for calling from other -programs. There is neither API nor Qhull classes. -It can be done, but it takes work and head scratching. +<p><b>Warning:</b> Qhull was not designed for calling from C +programs. It can be done, but it takes work and head scratching. 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 +<p>For examples of calling Qhull, see GNU Octave's <a href=http://octave.sourceforge.net/index/analysis.html#Geometry>computational geometry code</a>, and Qhull's <a href=../src/user_eg.c>user_eg.c</a>, -<a href=../src/user_eg2.c>user_eg2.c</a>, -<a href=../src/user.c>user.c</a>, and -<a href=../src/qhull_interface.cpp>qhull_interface.cpp</a>. -Qhull's programs use the same library: +<a href=../src/user_eg2.c>user_eg2.c</a>, and +<a href=../src/user.c>user.c</a>. To see how Qhull calls its library, read <a href=../src/unix.c>unix.c</a>, <a href=../src/qconvex.c>qconvex.c</a>, <a href=../src/qdelaun.c>qdelaun.c</a>, @@ -211,7 +443,7 @@ Qhull's programs use the same library: 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 +If you are interested in adapting BGL to Qhull, please contact <a href="mailto:bradb@qhull.org">bradb@qhull.org</a>. <p>See <a href="../src/index.htm">Qhull functions, macros, and data @@ -223,16 +455,16 @@ read the results from the output file.</p> <p>When you read the code, be aware of the macros "qh" and "qhstat", e.g., "qh hull_dim". They are -defined in <tt>qhull.h</tt>. They allow the global data +defined in <tt>qhulllib.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>qhull.h</tt>. +for inclusion in your programs. First review <tt>qhulllib.h</tt>. This defines the data structures used by Qhull and provides -prototypes for the top-level functions. -Most users will only need qhull.h in their programs. For -example, the Qhull program is defined with <tt>qhull.h</tt> and <tt>unix.c</tt>. +prototypes for the top-level functions. +Most users will only need qhulllib.h in their programs. For +example, the Qhull program is defined with <tt>qhulllib.h</tt> and <tt>unix.c</tt>. To access all functions, use <tt>qhull_a.h</tt>. Include the file with "<tt>#include <qhull/qhull_a.h>".</tt> This avoids potential name conflicts.</p> @@ -278,7 +510,7 @@ triangulation. </p> <pre> facetT *facet; vertexT *vertex, **vertexp; - + FORALLfacets { if (!facet->upperdelaunay) { printf ("%d", qh_setsize (facet->vertices); @@ -304,15 +536,15 @@ 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 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 +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 +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> @@ -348,13 +580,13 @@ qh_addpoint()</a></h3> 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://netlib.bell-labs.com/netlib/voronoi/hull.html">hull +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>qhull.c</tt>) to add a point to +<p>You may use qh_findbestfacet and qh_addpoint (<tt>qhulllib.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 @@ -385,16 +617,16 @@ intersections. The outline is: </p> <blockquote> <pre> initialize qhull with an initial set of points -qh_qhull(); +qh_qhull(); for each additional point p append p to the end of the point array or allocate p separately lift p to the paraboloid by calling qh_setdelaunay facet= qh_findbestfacet (p, !qh_ALL, &bestdist, &isoutside); - if (isoutside) + if (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> @@ -415,7 +647,7 @@ separation may be incorrect. [H. Geron] </p> <h3><A href="#TOC">»</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). +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 @@ -448,7 +680,7 @@ 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(); +qh_setvoronoi_all(); FORALLvertices { site_id = qh_pointid (vertex->point); if (qh hull_dim == 3) @@ -516,7 +748,7 @@ graph of the convex hull. </p> <pre>Here is a partial list: - fix finddelaunay() in user_eg.c for tricoplanar facets - - write a BGL, C++ interface to Qhull + - 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' @@ -529,12 +761,12 @@ 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. + - 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 + 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 + - 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 @@ -548,7 +780,7 @@ New features: - 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 + - 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] @@ -556,7 +788,7 @@ New features: - implement convex hull of moving points - implement constrained Delaunay diagrams see Shewchuk, ACM Symposium on Computational Geometry, Minneapolis 1998. - - estimate outer volume of hull + - estimate outer volume of hull - automatically determine lower dimensional hulls - allow "color" data for input points need to insert a coordinate for Delaunay triangulations @@ -577,7 +809,7 @@ Input/output improvements: Performance improvements: - optimize Qhull for 2-d Delaunay triangulations - use O'Rourke's <a href="index.htm#orou94">'94</a> vertex->duplicate_edge - - add bucketing + - 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] @@ -595,17 +827,17 @@ 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> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="#TOC">Qhull internals</a>: Table of Contents <br> +<b>To:</b> <a href="#TOC">Qhull code</a>: Table of Contents <br> <b>Dn:</b> <a href="../src/index.htm">Qhull functions</a>, macros, and data -structures <!-- GC common information --> +structures <!-- GC common information --> <hr> diff --git a/html/qh-eg.htm b/html/qh-eg.htm index 5fd2caa..168221b 100644 --- a/html/qh-eg.htm +++ b/html/qh-eg.htm @@ -48,7 +48,7 @@ test examples, and <tt>eg/q_test</tt> exercises the code. If you find yourself viewing the inside of a 3-d example, use Geomview's normalization option on the 'obscure' menu.</p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qh-faq.htm b/html/qh-faq.htm index a6c507e..2800611 100644 --- a/html/qh-faq.htm +++ b/html/qh-faq.htm @@ -6,7 +6,7 @@ content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Microsoft FrontPage 2.0"> <title>Qhull FAQ</title> -<!-- Navigation links +<!-- Navigation links NOTE -- verify all links by 'grep href=' 'grep name=' add # 'sort /+7' <base href> does not work since #TOC is relative to base instead of doc --> @@ -19,13 +19,13 @@ NOTE -- verify all links by 'grep href=' 'grep name=' add # 'sort /+7' (http://www.qhull.org)<br> <b>Up:</b> <A href="index.htm#TOC">Qhull manual</A>: Table of Contents<br> <b>To:</b> <A href="qh-quick.htm#programs">Programs</A> -• <A href="qh-quick.htm#options">Options</A> -• <A href="qh-opto.htm#output">Output</A> -• <A href="qh-optf.htm#format">Formats</A> -• <A href="qh-optg.htm#geomview">Geomview</A> +• <A href="qh-quick.htm#options">Options</A> +• <A href="qh-opto.htm#output">Output</A> +• <A href="qh-optf.htm#format">Formats</A> +• <A href="qh-optg.htm#geomview">Geomview</A> • <A href="qh-optp.htm#print">Print</A> -• <A href="qh-optq.htm#qhull">Qhull</A> -• <A href="qh-optc.htm#prec">Precision</A> +• <A href="qh-optq.htm#qhull">Qhull</A> +• <A href="qh-optc.htm#prec">Precision</A> • <A href="qh-optt.htm#trace">Trace</A> <br> <b>To:</b> <A href="#TOC">FAQ: Table of Contents</A> (please wait while loading) <br> @@ -41,12 +41,12 @@ wait while loading) <br> <p>If your question does not appear here, see: </p> <ul> - <li><a href="http://www.qhull.org/news">News</a> about Qhull - <li><A href="index.htm#TOC">Qhull manual:</A> table of contents - <li><A href="../README.txt">Installation</A> instructions for Qhull and rbox + <li><a href="http://www.qhull.org/news">News</a> about Qhull + <li><A href="index.htm#TOC">Qhull manual:</A> table of contents + <li><A href="../README.txt">Installation</A> instructions for Qhull and rbox - <li><A href="mailto:qhull@qhull.org">Send e-mail</A> to - qhull@qhull.org + <li><A href="mailto:qhull@qhull.org">Send e-mail</A> to + qhull@qhull.org <li><A href="mailto:qhull_bug@qhull.org">Report bugs</A> to qhull_bug@qhull.org </li> </ul> @@ -69,29 +69,29 @@ run the same code. It should be used for Delaunay triangulations instead of using joggled input ('<A href="qh-optq.htm#QJn">QJ</A>'). -<p><i>Brad Barber, Cambridge MA, +<p><i>Brad Barber, Cambridge MA, 2003/12/30 <!-- --> </i></p> -<p><b>Copyright © 1998-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1998-2008 The Geometry Center, Minneapolis MN</b></p> <hr> <h2><A href="#TOP">»</A><a name="TOC">FAQ: Table of Contents </a></h2> <p>Within each category, the most recently asked questions are -first. +first. <ul> <li>Startup questions <ul> - <li><A href="#console">How</A> do I run Qhull from Windows? - <li><A href="#input">How</A> do I enter points for Qhull? + <li><A href="#console">How</A> do I run Qhull from Windows? + <li><A href="#input">How</A> do I enter points for Qhull? <li><A href="#learn">How</A> do I learn to use Qhull?</li> </ul> <li>Convex hull questions<ul> - <li><A href="#area">How</A> do I report just the area and volume of a - convex hull? - <li><A href="#extra">Why</A> are there extra points in a 4-d or higher - convex hull? + <li><A href="#area">How</A> do I report just the area and volume of a + convex hull? + <li><A href="#extra">Why</A> are there extra points in a 4-d or higher + convex hull? <li><A href="#dup">How</A> do I report duplicate vertices? </li> </ul> @@ -99,32 +99,32 @@ first. <li><a href="#maxsphere">How</a> do I get the radii of the empty spheres for each Voronoi vertex? - <li><A href="#flat">How</A> do I get rid of nearly flat Delaunay - triangles? - - <li><A href="#square">What</A> is the Voronoi diagram of a square? - - <li><A href="#vclosest">How</A> do I find the Delaunay triangle or Voronoi - region that is closest to a point? - - <li><A href="#mesh">How</A> do I compute the Delaunay triangulation of a - non-convex object? - - <li><A href="#mesh">How</A> do I mesh a volume from a set of triangulated - surface points? - - <li><A href="#constrained">Can</A> Qhull produce a triangular mesh for an - object? - - <li><A href="#dridges">For</A> 3-d Delaunay triangulations, how do I - report the triangles of each tetrahedron? - <li><A href="#vsphere">How</A> do I construct the Voronoi diagram of - cospherical points? - <li><A href="#3dd">How</A> do I construct a 3-d Delaunay triangulation? - <li><A href="#2d">How</A> do I get the triangles for a 2-d Delaunay - triangulation and the vertices of its Voronoi diagram? - <li><A href="#rays">Can</A> Qhull compute the unbounded rays of the - Voronoi diagram? + <li><A href="#flat">How</A> do I get rid of nearly flat Delaunay + triangles? + + <li><A href="#square">What</A> is the Voronoi diagram of a square? + + <li><A href="#vclosest">How</A> do I find the Delaunay triangle or Voronoi + region that is closest to a point? + + <li><A href="#mesh">How</A> do I compute the Delaunay triangulation of a + non-convex object? + + <li><A href="#mesh">How</A> do I mesh a volume from a set of triangulated + surface points? + + <li><A href="#constrained">Can</A> Qhull produce a triangular mesh for an + object? + + <li><A href="#dridges">For</A> 3-d Delaunay triangulations, how do I + report the triangles of each tetrahedron? + <li><A href="#vsphere">How</A> do I construct the Voronoi diagram of + cospherical points? + <li><A href="#3dd">How</A> do I construct a 3-d Delaunay triangulation? + <li><A href="#2d">How</A> do I get the triangles for a 2-d Delaunay + triangulation and the vertices of its Voronoi diagram? + <li><A href="#rays">Can</A> Qhull compute the unbounded rays of the + Voronoi diagram? <li><A href="#big">Can </A>Qhull triangulate a hundred 16-d points?</li> </ul> @@ -137,26 +137,26 @@ first. intersection of halfspaces with Qhull?</li> </ul> <li><a name="library">Qhull library</a> questions<ul> - <li><A href="#math">Is</A> Qhull available for Mathematica, Matlab, or - Maple? - - <li><A href="#ridges">Why</A> are there too few ridges? - <li><A href="#call">Can</A> Qhull use coordinates without placing them in - a data file? - <li><A href="#size">How</A> large are Qhull's data structures? - <li><A href="#inc">Can</A> Qhull construct convex hulls and Delaunay - triangulations one point at a time? - <li><A href="#ridges2">How</A> do I visit the ridges of a Delaunay - triangulation? - <li><A href="#listd">How</A> do I visit the Delaunay facets? - <LI><A - href="#outside">When</A> is a point outside or inside a facet? - <li><A href="#closest">How</A> do I find the facet that is closest to a - point? - <li><A href="#vclosest">How</A> do I find the Delaunay triangle or Voronoi - region that is closest to a point? - <li><A href="#vertices">How</A> do I list the vertices? - <li><A href="#test">How</A> do I test code that uses the Qhull library? + <li><A href="#math">Is</A> Qhull available for Mathematica, Matlab, or + Maple? + + <li><A href="#ridges">Why</A> are there too few ridges? + <li><A href="#call">Can</A> Qhull use coordinates without placing them in + a data file? + <li><A href="#size">How</A> large are Qhull's data structures? + <li><A href="#inc">Can</A> Qhull construct convex hulls and Delaunay + triangulations one point at a time? + <li><A href="#ridges2">How</A> do I visit the ridges of a Delaunay + triangulation? + <li><A href="#listd">How</A> do I visit the Delaunay facets? + <LI><A + href="#outside">When</A> is a point outside or inside a facet? + <li><A href="#closest">How</A> do I find the facet that is closest to a + point? + <li><A href="#vclosest">How</A> do I find the Delaunay triangle or Voronoi + region that is closest to a point? + <li><A href="#vertices">How</A> do I list the vertices? + <li><A href="#test">How</A> do I test code that uses the Qhull library? <li><A href="#orient">When</A> I compute a plane equation from a facet, I sometimes get an outward-pointing normal and sometimes an @@ -174,26 +174,26 @@ from Windows?</h4><blockquote> <p>Qhull is a console program. You will first need a DOS window (i.e., a "DOS prompt"). You can double click on -'eg\Qhull-go.bat'. It loads 'doskey' to simplify rerunning qhull +'eg\Qhull-go.bat'. It loads 'doskey' to simplify rerunning qhull and rbox. </p> <blockquote><ul> - <li>Type 'qconvex', 'qdelaunay', 'qhalf', 'qvoronoi, - 'qhull', and 'rbox' for a synopsis of each program. - - <li>Type 'rbox c D2 | qconvex s i' to compute the - convex hull of a square. - - <li>Type 'rbox c D2 | qconvex s i TO results.txt' to - write the results to the file 'results.txt'. A summary is still printed on - the the console. - - <li>Type 'rbox c D2' to see the input format for - qconvex. - - <li>Type 'qconvex < data.txt s i TO results.txt' to - read input data from 'data.txt'. - + <li>Type 'qconvex', 'qdelaunay', 'qhalf', 'qvoronoi, + 'qhull', and 'rbox' for a synopsis of each program. + + <li>Type 'rbox c D2 | qconvex s i' to compute the + convex hull of a square. + + <li>Type 'rbox c D2 | qconvex s i TO results.txt' to + write the results to the file 'results.txt'. A summary is still printed on + the the console. + + <li>Type 'rbox c D2' to see the input format for + qconvex. + + <li>Type 'qconvex < data.txt s i TO results.txt' to + read input data from 'data.txt'. + <li>If you want to enter data by hand, type 'qconvex s i TO results.txt' to read input data from the console. Type in the numbers and end with a ctrl-D. </li> @@ -238,51 +238,51 @@ use Qhull?</h4><blockquote> <p>First read: </p> <ul> - <li><A href="index.htm">Introduction</A> to Qhull - <li><A href="index.htm#when">When</A> to use Qhull - <li><A href="qconvex.htm">qconvex</A> -- convex hull - <li><A href="qdelaun.htm">qdelaunay</A> -- Delaunay triangulation - <li><A href="qhalf.htm">qhalf</A> -- half-space intersection about a point - - <li><A href="qvoronoi.htm">qvoronoi</A> -- Voronoi diagram - <li><A href="rbox.htm">Rbox</A>, for sample inputs + <li><A href="index.htm">Introduction</A> to Qhull + <li><A href="index.htm#when">When</A> to use Qhull + <li><A href="qconvex.htm">qconvex</A> -- convex hull + <li><A href="qdelaun.htm">qdelaunay</A> -- Delaunay triangulation + <li><A href="qhalf.htm">qhalf</A> -- half-space intersection about a point + + <li><A href="qvoronoi.htm">qvoronoi</A> -- Voronoi diagram + <li><A href="rbox.htm">Rbox</A>, for sample inputs <li><A href="qh-eg.htm">Examples</A> of Qhull</li> </ul> <p>Look at Qhull's on-line documentation: </p> <ul> - <li>'qconvex' gives a synopsis of qconvex and its options + <li>'qconvex' gives a synopsis of qconvex and its options - <li>'rbox' lists all of the options for generating point - sets - <li>'qconvex - | more' lists the options for qconvex - <li>'qconvex .' gives a concise list of options + <li>'rbox' lists all of the options for generating point + sets + <li>'qconvex - | more' lists the options for qconvex + <li>'qconvex .' gives a concise list of options <li>'qdelaunay', 'qhalf', 'qvoronoi', and 'qhull' also have a synopsis and option list</li> </ul> <p>Then try out the Qhull programs on small examples. </p> <ul> - <li>'rbox c' lists the vertices of a cube - <li>'rbox c | qconvex' is the convex hull of a cube - <li>'rbox c | qconvex o' lists the vertices and facets of - a cube - <li>'rbox c | qconvex Qt o' triangulates the cube - <li>'rbox c | qconvex QJ o' joggles the input and - triangulates the cube - <li>'rbox c D2 | qconvex' generates the convex hull of a - square - <li>'rbox c D4 | qconvex' generates the convex hull of a - hypercube - <li>'rbox 6 s D2 | qconvex p Fx' lists 6 random points in - a circle and lists the vertices of their convex hull in order - <li>'rbox c D2 c G2 | qdelaunay' computes the Delaunay - triangulation of two embedded squares. It merges the cospherical facets. - <li>'rbox c D2 c G2 | qdelaunay Qt' computes the Delaunay - triangulation of two embedded squares. It triangulates the cospherical facets. - <li>'rbox c D2 c G2 | qvoronoi o' computes the - corresponding Voronoi vertices and regions. + <li>'rbox c' lists the vertices of a cube + <li>'rbox c | qconvex' is the convex hull of a cube + <li>'rbox c | qconvex o' lists the vertices and facets of + a cube + <li>'rbox c | qconvex Qt o' triangulates the cube + <li>'rbox c | qconvex QJ o' joggles the input and + triangulates the cube + <li>'rbox c D2 | qconvex' generates the convex hull of a + square + <li>'rbox c D4 | qconvex' generates the convex hull of a + hypercube + <li>'rbox 6 s D2 | qconvex p Fx' lists 6 random points in + a circle and lists the vertices of their convex hull in order + <li>'rbox c D2 c G2 | qdelaunay' computes the Delaunay + triangulation of two embedded squares. It merges the cospherical facets. + <li>'rbox c D2 c G2 | qdelaunay Qt' computes the Delaunay + triangulation of two embedded squares. It triangulates the cospherical facets. + <li>'rbox c D2 c G2 | qvoronoi o' computes the + corresponding Voronoi vertices and regions. <li>'rbox c D2 c G2 | qvoronio Fv' shows the Voronoi diagram for the previous example. Each line is one edge of the diagram. The first number is 4, the next two numbers list @@ -306,11 +306,11 @@ problems. It can triangulate the output ('<A href="qh-optq.htm#QJn" >QJ</A>'), or merge facets (the default). </p> <ul> - <li>With joggle, Qhull produces simplicial (i.e., + <li>With joggle, Qhull produces simplicial (i.e., triangular) output by joggling the input. After joggle, no points are cocircular or cospherical. - <li>With facet merging, Qhull produces a better - approximation and does not modify the input. + <li>With facet merging, Qhull produces a better + approximation and does not modify the input. <li>With triangulated output, Qhull merges facets and triangulates the result.</li> <li>See <A href="qh-impre.htm#joggle">Merged facets or joggled input</A>. </li> @@ -354,7 +354,7 @@ points in a 4-d or higher convex hull?</h4><blockquote> without using triangulated output ('<A href="qh-optq.htm#Qt">Qt</A>'). The extra points occur when a facet is non-simplicial (i.e., a facet with more than <i>d</i> vertices). For example, Qhull -reports the following for one facet of the convex hull of a hypercube. +reports the following for one facet of the convex hull of a hypercube. Option 'Pd0:0.5' returns the facet along the positive-x axis: </p> <blockquote> @@ -456,7 +456,7 @@ rbox c D4 | qconvex Pd0:0.5 Ft </blockquote><h4><A href="#TOC">»</A><a name="dup">How</a> do I report duplicate vertices?</h4><blockquote> -<p>There's no direct way. You can use option +<p>There's no direct way. You can use option '<A href="qh-optf.htm#FP">FP</A>' to report the distance to the nearest vertex for coplanar input points. Select the minimum distance for a duplicated vertex, and @@ -481,13 +481,13 @@ minimum distance for each Voronoi vertex. <p>There's other ways to get the same information. Let me know if you find a better method. -<h4><A href="#TOC">»</A><a name="flat">How</a> do I get rid of +<h4><A href="#TOC">»</A><a name="flat">How</a> do I get rid of nearly flat Delaunay triangles?</h4><blockquote> <p>Nearly flat triangles occur when boundary points are nearly collinear or coplanar. They also occur for nearly coincident points. Both events can easily occur when using joggle. For example -(rbox 10 W0 D2 | qdelaunay QJ Fa) lists the areas of the Delaunay +(rbox 10 W0 D2 | qdelaunay QJ Fa) lists the areas of the Delaunay triangles of 10 points on the boundary of a square. Some of these triangles are nearly flat. This occurs when one point is joggled inside of two other points. In this case, nearly flat @@ -497,25 +497,25 @@ triangles do not occur with triangulated output (rbox 10 W0 D2 | qdelaunay Qt Fa <p>Another example, (rbox c P0 P0 D2 | qdelaunay QJ Fa), computes the areas of the Delaunay triangles for the unit square and two instances of the origin. Four of the triangles have an area -of 0.25 while two have an area of 2.0e-11. The later are due to +of 0.25 while two have an area of 2.0e-11. The later are due to the duplicated origin. With triangulated output (rbox c P0 P0 D2 | qdelaunay Qt Fa) there are four triangles of equal area. <p>Nearly flat triangles also occur without using joggle. For example, (rbox c P0 P0,0.4999999999 | qdelaunay Fa), computes -the areas of the Delaunay triangles for the unit square, +the areas of the Delaunay triangles for the unit square, a nearly collinear point, and the origin. One triangle has an area of 3.3e-11. -<p>Unfortunately, none of Qhull's merging options remove nearly +<p>Unfortunately, none of Qhull's merging options remove nearly flat Delaunay triangles due to nearly collinear or coplanar boundary -points. +points. The merging options concern the empty circumsphere property of Delaunay triangles. This is independent of the area of -the Delaunay triangles. Qhull does handle nearly coincident points. +the Delaunay triangles. Qhull does handle nearly coincident points. -<p>You can handle collinear or coplanar boundary points by -enclosing the points in a box. For example, +<p>You can handle collinear or coplanar boundary points by +enclosing the points in a box. For example, (rbox c P0 P0,0.4999999999 c G1 | qdelaunay Fa), surrounds the previous points with [(1,1), (1,-1), (-1,-1), (-1, 1)]. Its Delaunay triangulation does not include a @@ -525,7 +525,7 @@ output from Qhull. <p>Without joggle, Qhull lists coincident points as "coplanar" points. For example, (rbox c P0 P0 D2 | qdelaunay Fa), ignores the duplicated origin and lists four triangles of size 0.25. -Use 'Fc' to list the coincident points (e.g., +Use 'Fc' to list the coincident points (e.g., rbox c P0 P0 D2 | qdelaunay Fc). <p>There is no easy way to determine coincident points with joggle. @@ -539,9 +539,9 @@ or triangulated output ('<A href="qh-optq.htm#Qt">Qt</A>'). of a square?</h4><blockquote> <p> -Consider a square, +Consider a square, <blockquote><pre> -C:\qhull>rbox c D2 +C:\qhull>rbox c D2 2 RBOX c D2 4 -0.5 -0.5 @@ -592,15 +592,15 @@ C:\qhull>rbox c D2 | qvoronoi Qz Fv </pre></blockquote> <p>There is one Voronoi vertex at the origin and rays from the origin -along each of the coordinate axes. +along each of the coordinate axes. The last line '4 2 3 0 1' means that there is a ray that bisects input points #2 and #3 from infinity (vertex 0) to -the origin (vertex 1). +the origin (vertex 1). Option 'Qz' adds an artificial point since the input is cocircular. Coordinates -10.101 indicate the -vertex at infinity. +vertex at infinity. -<p>With triangulated output, the Voronoi vertex is +<p>With triangulated output, the Voronoi vertex is duplicated: <blockquote><pre> @@ -644,7 +644,7 @@ C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz Fv </pre></blockquote> -<p>With joggle, the input is no longer cocircular and the Voronoi vertex is +<p>With joggle, the input is no longer cocircular and the Voronoi vertex is split into two: <blockquote><pre> @@ -670,14 +670,14 @@ C:\qhull>rbox c D2 | qvoronoi QJ Fv 4 2 3 0 2 </pre></blockquote> -<p>Note that the Voronoi diagram includes the same rays as - before plus a short edge between the two vertices.</p> - +<p>Note that the Voronoi diagram includes the same rays as + before plus a short edge between the two vertices.</p> + </blockquote><h4><A href="#TOC">»</A><a name="mesh">How</a> do I compute the Delaunay triangulation of a non-convex object?</h4><blockquote> -<p>A similar question is +<p>A similar question is "How do I mesh a volume from a set of triangulated surface points?" <p>This is an instance of the constrained Delaunay Triangulation @@ -687,16 +687,16 @@ contains enough points, the triangulation will include the boundary. The number of points needed depends on the input. <p>Shewchuk has developed a theory of constrained Delaunay triangulations. -See his +See his <a href="http://www.cs.cmu.edu/~jrs/jrspapers.html#cdt">paper</a> at the 1998 Computational Geometry Conference. Using these ideas, constraints could be added to Qhull. They would have many applications. <p>There is a large literature on mesh generation and many commercial -offerings. For pointers see -<a href="http://www.andrew.cmu.edu/user/sowen/mesh.html">Owen's Meshing -Research Corner</a> and -<a href="http://www-users.informatik.rwth-aachen.de/~roberts/meshgeneration.html">Schneiders' +offerings. For pointers see +<a href="http://www.andrew.cmu.edu/user/sowen/mesh.html">Owen's Meshing +Research Corner</a> and +<a href="http://www-users.informatik.rwth-aachen.de/~roberts/meshgeneration.html">Schneiders' Finite Element Mesh Generation page</a>.</p> </blockquote><h4><A href="#TOC">»</A><a name="constrained">Can</a> Qhull @@ -716,8 +716,8 @@ generates tetrahedron. Each face of a tetrahedron is a triangle. For example, the 3-d Delaunay triangulation of random points on the surface of a cube, is a cellular structure of tetrahedron. </p> -<p>Use triangulated output ('qdelaunay Qt i') or joggled input ('qdelaunay QJ i') -to generate the Delaunay triangulation. +<p>Use triangulated output ('qdelaunay Qt i') or joggled input ('qdelaunay QJ i') +to generate the Delaunay triangulation. Option 'i' reports each tetrahedron. The triangles are every combination of 3 vertices. Each triangle is a "ridge" of the Delaunay triangulation. </p> @@ -821,7 +821,7 @@ for point 0. Point 0 is [0,0,-1]. Its Voronoi vertices are </p> -0.5773502691896258 0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 - 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 + 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 </pre> <p>In this case, the Voronoi vertices are oriented, but in @@ -853,17 +853,17 @@ input sites {3, 1, 4} (i.e., {[0,1,0], [0,0,1], [-1,0,0]}). </p> </blockquote><h4><A href="#TOC">»</A><a name="3dd">How</a> do I construct a 3-d Delaunay triangulation?</h4><blockquote> -<p>For 3-d Delaunay triangulations with cospherical input sites, +<p>For 3-d Delaunay triangulations with cospherical input sites, use triangulated output ('<A href="qh-optq.htm#Qt">Qt</A>') or joggled input ('<A href="qh-optq.htm#QJn">QJ</A>'). Otherwise option 'i' will triangulate non-simplicial facets by adding a point to the facet. <p>If you want non-simplicial output for cospherical sites, use -option +option '<A href="qh-optf.htm#Fv">Fv</A>' or '<A href="qh-opto.htm#o">o</A>'. For option 'o', ignore the last coordinate. It is the lifted -coordinate for the corresponding convex hull in 4-d. +coordinate for the corresponding convex hull in 4-d. <p>The following example is a cube inside a tetrahedron. The 8-vertex facet is the cube. Ignore the @@ -911,7 +911,7 @@ C:\qhull>rbox r y c G0.1 | qdelaunay Fv <p>If you want simplicial output use options '<A href="qh-optq.htm#Qt">Qt</A> <A - href="qh-optf.htm#Ft" >i</A>' or + href="qh-optf.htm#Ft" >i</A>' or '<A href="qh-optq.htm#QJn">QJ</A> <A href="qh-optf.htm#Ft" >i</A>', e.g., </p> @@ -979,7 +979,7 @@ diagram for each pair of adjacent input sites, use</p> <p>rbox 10 D2 | qvoronoi Fv </p> </blockquote> -<p>To compute the area and volume of the Voronoi region for input site 5, +<p>To compute the area and volume of the Voronoi region for input site 5 (site 0 is the first one), use </p> <blockquote> @@ -1093,11 +1093,11 @@ hull problem. <p>Use linear programming if you do not know a point in the interior of the halfspaces. -See the <A href="qhalf.htm#notes">manual</A>. You will need - a linear programming code. This may require a fair amount of work to - implement.</p> - - +See the <A href="qhalf.htm#notes">manual</A>. You will need + a linear programming code. This may require a fair amount of work to + implement.</p> + + </blockquote> <h2><A href="#TOC">»</A><a name="library">Qhull library @@ -1105,25 +1105,33 @@ questions</a></h2> <h4><A href="#TOC">»</A><a name="math">Is</a> Qhull available for Mathematica, Matlab, or Maple?</h4><blockquote> -<p>Z. You of <a href="http://www.mathworks.com">MathWorks</a> added qhull to MATLAB 6. -See functions <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/convhulln.shtml" +<p><b>MATLAB</b> + +<p>Z. You of <a href="http://www.mathworks.com">MathWorks</a> added qhull to MATLAB 6. +See functions <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/convhulln.shtml" >convhulln</a>, - <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/delaunayn.shtml" + <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/delaunayn.shtml" >delaunayn</a>, - <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/griddata3.shtml" + <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/griddata3.shtml" >griddata3</a>, - <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/griddatan.shtml" + <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/griddatan.shtml" >griddatan</a>, - <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/tsearch.shtml" + <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/tsearch.shtml" >tsearch</a>, - <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/tsearchn.shtml" + <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/tsearchn.shtml" >tsearchn</a>, and - <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/voronoin.shtml" - >voronoin</a>. V. Brumberg update MATLAB R14 for Qhull 2003.1 and triangulated output. + <a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/voronoin.shtml" + >voronoin</a>. V. Brumberg update MATLAB R14 for Qhull 2003.1 and triangulated output. -<p>See <a href="http://www.mathsource.com/Content/Enhancements/Geometry/0211-251" +<p>Engwirda wrote <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=10307&objectType=file">mesh2d</a> for unstructured mesh generation in MATLAB. +It is based on the iterative method of Persson and generally results in better quality meshes than delaunay refinement. + + +<p><b>Mathematica and Maple</b> + +<p>See <a href="http://library.wolfram.com/infocenter/MathSource/1160/" >qh-math</a> -for a Delaunay interface to Mathematica. It includes projects for CodeWarrior +for a Delaunay interface to Mathematica. It includes projects for CodeWarrior on the Macintosh and Visual C++ on Win32 PCs. <p>See Mathematica ('<a @@ -1141,7 +1149,7 @@ The following sample code may produce fewer ridges than expected: FORALLfacets { printf("facet f%d\n", facet->id); - FOREACHridge_(facet->ridges) { + FOREACHridge_(facet->ridges) { printf(" ridge r%d between f%d and f%d\n", ridge->id, ridge->top->id, ridge->bottom->id); } } @@ -1175,13 +1183,13 @@ each ridge once (instead of twice). For example, <p>Use qh_call_qhull(). See user_eg.c for an example. See the manual for an introduction to the Qhull library. -<p>Start with a small example for which you know the - answer.</p> +<p>Start with a small example for which you know the + answer.</p> </blockquote><h4><A href="#TOC">»</A><a name="size">How</a> large are Qhull's data structures?</h4><blockquote> -<p>Qhull uses a general-dimension data structure. +<p>Qhull uses a general-dimension data structure. The size depends on the dimension. Use option 'Ts' to print out the memory statistics [e.g., 'rbox D2 10 | qconvex Ts']. @@ -1373,11 +1381,11 @@ Voronoi region. Do not use options '<A href="qh-optq.htm#Qbb">Qbb</A>', '<A href="qh-optq.htm#QbB">QbB</A>', '<A href="qh-optq.htm#Qbk">Qbk:n</A>', or '<A href="qh-optq.htm#QBk" >QBk:n</A>' since these scale the last -coordinate. Optimizations of qh_findbestfacet() should +coordinate. Optimizations of qh_findbestfacet() should be possible for Delaunay triangulations.</p> -<p>You first need to lift the point to the paraboloid (i.e., the -last coordinate is the sum of the squares of the point's coordinates). +<p>You first need to lift the point to the paraboloid (i.e., the +last coordinate is the sum of the squares of the point's coordinates). The routine, qh_setdelaunay() [geom2.c], lifts an array of points to the paraboloid. The following excerpt is from findclosest() in @@ -1399,12 +1407,12 @@ user_eg.c. </p> <p>The returned facet either contains the point or it is the closest Delaunay triangle along the convex hull of the input set. -<p>Point location is an active research area in Computational +<p>Point location is an active research area in Computational Geometry. For a practical approach, see Mucke, et al, "Fast randomized point location without preprocessing in two- and three-dimensional Delaunay triangulations," <i>Computational -Geometry '96</i>, p. 274-283, May 1996. -For an introduction to planar point location see [O'Rourke '93]. +Geometry '96</i>, p. 274-283, May 1996. +For an introduction to planar point location see [O'Rourke '93]. Also see, "<A href="#closest" >How</A> do I find the facet that is closest to a point?" </p> @@ -1438,11 +1446,11 @@ use </p> <blockquote> <pre> vertexT *vertex; - + FORALLvertices { ... // vertex->point is the coordinates of the vertex - // qh_pointid (vertex->point) is the point ID of the vertex + // qh_pointid(vertex->point) is the point ID of the vertex ... } </pre> @@ -1467,8 +1475,8 @@ normal and sometimes an inward-pointing normal</h4><blockquote> for 'i', 'Ft', and other options. The orientation depends on <i>both</i> the vertex order and the flag facet->toporient.</p> -<p>Qhull does not orient - non-simplicial facets. Instead it orients the facet's ridges. These are +<p>Qhull does not orient + non-simplicial facets. Instead it orients the facet's ridges. These are printed with the 'Qt' and 'Ft' option. The facet's hyperplane is oriented. </p> </blockquote> @@ -1478,13 +1486,13 @@ the vertex order and the flag facet->toporient.</p> href="http://www.qhull.org">Home page for Qhull</a><br> <b>Up:</b> <A href="index.htm#TOC">Qhull manual</A>: Table of Contents <br> <b>To:</b> <A href="qh-quick.htm#programs">Programs</A> -• <A href="qh-quick.htm#options">Options</A> -• <A href="qh-opto.htm#output">Output</A> -• <A href="qh-optf.htm#format">Formats</A> -• <A href="qh-optg.htm#geomview">Geomview</A> +• <A href="qh-quick.htm#options">Options</A> +• <A href="qh-opto.htm#output">Output</A> +• <A href="qh-optf.htm#format">Formats</A> +• <A href="qh-optg.htm#geomview">Geomview</A> • <A href="qh-optp.htm#print">Print</A> -• <A href="qh-optq.htm#qhull">Qhull</A> -• <A href="qh-optc.htm#prec">Precision</A> +• <A href="qh-optq.htm#qhull">Qhull</A> +• <A href="qh-optc.htm#prec">Precision</A> • <A href="qh-optt.htm#trace">Trace</A> <br> <b>To:</b> <A href="#TOC">FAQ: Table of Contents</A><br><!-- GC common information --> @@ -1496,8 +1504,8 @@ 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 top +Created: +Sept. 25, 1995 --- <!-- hhmts start -->Last modified: see top <!-- hhmts end --> </p> </body> </html> diff --git a/html/qh-get.htm b/html/qh-get.htm index dfcb374..eaf7ffa 100644 --- a/html/qh-get.htm +++ b/html/qh-get.htm @@ -7,8 +7,7 @@ <body> <!-- Navigation links --> -<p><b>Up:</b> <a href="http://www.geom.uiuc.edu/software/download"><i>Downloadable Software from the -Geometry Center </i></a><br> +<p><b>Up:</b> <a href="http://www.qhull.org"><i>Qhull Home Page</i></a><br> </p> <hr> @@ -20,9 +19,9 @@ width="100" height="100"></a> Qhull Downloads</h1> <ul> <li><a href="http://www.qhull.org">Qhull Home Page</a> <p>Qhull - computes convex hulls, Delaunay triangulations, halfspace - intersections about a point, Voronoi diagrams, furthest-site Delaunay - triangulations, and furthest-site Voronoi diagrams. It + 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 @@ -38,32 +37,52 @@ width="100" height="100"></a> Qhull Downloads</h1> <p>Includes executables, documentation, sources files, and a cygwin Makefile. It runs in a DOS window.</p> </li> - <li><a href="http://www.qhull.org/download/qhull-2003.1-src.tgz">Download: - source for Qhull 2003.1</a> (600K) <p>Type: C source code for - 32-bit and 64-bit architectures </p> - <p>Includes documentation, source files, and a simple Makefile</p> - </li> - <li><a href=http://savannah.nongnu.org/files/?group=qhull>Download: Qhull 2002.1 for Unix</a> - <p>Type: C source code for Unix systems (Debian configure)</b> - - <p>Includes documentation, source files, and a configure Makefile. + <li><a href="http://www.qhull.org/download/qhull-2003.1.tar.gz">Download: Qhull 2003.1 for Unix</a> (725K) + <p>Type: C source code for Unix systems</b> + <p>Includes documentation, source files, and Autoconf/Automake/Libtool + support [R. Laboissiere]. + If using gcc-4 or later, please compile qset.s with + -fno-strict-aliasing (otherwise qhull segfaults) [Karas, Krishnaswami]. + See <a href=http://www.qhull.org/news/#bugs>Bugs</a> [Apr 2008] for a patch. + </p> + +<!--- + <li><a href=http://savannah.nongnu.org/files/?group=qhull>Download: Qhull 2002.1 for Unix</a> + + <p>Includes documentation, source files, and a configure Makefile. Includes Debian configuration files. Includes downloads of Qhull's current and previous versions.</p> - <!--- - <p>B. Pearlmutter created a + <p>B. Pearlmutter created a <a href=http://packages.debian.org/stable/math/qhull-bin.html>Debian build</a> of Qhull 3.1 -and upgraded it to 2002.1. +and upgraded it to 2002.1. --> - </li> - <li><a href="http://www.qhull.org/download/qhull-2002.1-1mdk.i686.rpm">Download: - Qhull version 2002.1 i686 rpm</a> (643K) <p>Type: rpm build for Mandrake 8.2 and RedHat 7.3</p> - - <p>For other Linux systems, use the <a href="http://www.qhull.org/download/qhull-2002.1-1mdk.src.rpm">src rpm</a> [L. Mazet] + <li><a href="http://www.qhull.org/download/qhull-2003.1-src.tgz">Download: + Qhull 2003.1 source code</a> (450K) <p>Type: C source code for + 32-bit and 64-bit architectures </p> + <p>Includes documentation, source files, and a simple Makefile. + If using gcc-4 or later, please compile qset.s with + -fno-strict-aliasing (otherwise qhull segfaults) [Karas, Krishnaswami]. + See <a href=http://www.qhull.org/news/#bugs>Bugs</a> [Apr 2008] for a patch. + </p> + </li> + + <li><a href="http://www.qhull.org/download/qhull-2003.1-1mdk.i686.rpm">Download: + Qhull version 2003.1 i686 rpm</a> (670K) <p>Type: rpm build for Mandrake 9.2 and RedHat + [<a href="http://www.qhull.org/download/qhull.spec">qhull.spec</a>]</p> + + <p>For other Linux systems, use the <a href="http://www.qhull.org/download/qhull-2003.1-1mdk.src.rpm">src rpm</a> [L. Mazet] </li> - <li><a href=http://savannah.gnu.org/projects/qhull/>Qhull@Savannah</a> + + <li><a href="http://packages.debian.org/search?keywords=qhull">Download: + Qhull 2003.1 for Debian</a> + <p>Type: Debian packages + <p>Includes documentation, source files, and previous distributions [R. Laboissiere].</p> + </li> + + <li><a href=http://savannah.nongnu.org/projects/qhull/>Qhull@Savannah</a> <p>Type: CVS repository</b> <p>CVS repositiory of Qhull sources, documentation, and Makefiles. @@ -71,17 +90,16 @@ and upgraded it to 2002.1. </li> <li><a href=http://www6.uniovi.es/ftp/pub/mirrors/geom.umn.edu/software/ghindex.html>Spanish mirror site</a> <p>Download Qhull's current and - previous versions from <a href=http://www.etsimo.uniovi.es/derechos.html>Servidor + previous versions from <a href=http://www.etsimo.uniovi.es/derechos.html>Servidor WWW de la Escuela de Minas</a> of the Universidad de Oviedo.</p> </li> <li><a - href="http://citeseer.nj.nec.com/83502.html">Download: + href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.54.6345&rep=rep1&type=pdf">Download: Article about Qhull</a> (210K) <p>Type: various formats on CiteSeer</p> <p>Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull algorithm for convex hulls," <i>ACM - Transactions on Mathematical Software</i>, vol. 22, pp. - 469-483, Dec 1996 [<a - href="http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/">abstract</a>].</p> + 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-1.0.tar.gz">Download: @@ -111,8 +129,7 @@ and upgraded it to 2002.1. <!-- Navigation links --> <hr> -<p><b>Up:</b> <a href="http://www.geom.uiuc.edu/software/download"><i>Downloadable Software from the -Geometry Center </i></a><br> +<p><b>Up:</b> <a href="http://www.qhull.org"><i>Qhull Home Page</i></a><br> <!-- GC common information --></p> <hr> diff --git a/html/qh-impre.htm b/html/qh-impre.htm index c18c585..4bfa8af 100644 --- a/html/qh-impre.htm +++ b/html/qh-impre.htm @@ -12,13 +12,13 @@ page</a> for Qhull <br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> <b>To: </b><a href="#TOC">Qhull imprecision</a>: Table of Contents (please wait while loading) @@ -46,7 +46,7 @@ convex. It verifies that all points are on or below all facets. </p> <p>Qhull automatically tests for convexity if it detects precision errors while constructing the hull. </p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> @@ -57,6 +57,7 @@ imprecision: Table of Contents </a></h2> <li><a href="#prec">Precision problems</a></li> <li><a href="#joggle">Merged facets or joggled input</a></li> <li><a href="#delaunay">Delaunay triangulations</a></li> + <li><a href="#halfspace">Halfspace intersection/a></li> <li><a href="#imprecise">Merged facets</a></li> <li><a href="#how">How Qhull merges facets</a></li> <li><a href="#limit">Limitations of merged facets</a></li> @@ -70,7 +71,7 @@ imprecision: Table of Contents </a></h2> <h2><a href="#TOC">»</a><a name="prec">Precision problems</a></h2> <p>Since Qhull uses floating point arithmetic, roundoff error -occurs with each calculation. This causes problems for +occurs with each calculation. This causes problems for geometric algorithms. Other floating point codes for convex hulls, Delaunay triangulations, and Voronoi diagrams also suffer from these problems. Qhull handles most of them.</p> @@ -119,8 +120,8 @@ modification is tried. When no precision errors occur, Qhull is done. </p> <p>Qhull 3.1 and later provides option '<a href="qh-optq.htm#Qt">Qt</a>' -for triangulated output. This removes the need for -joggled input ('<a href="qh-optq.htm#QJn">QJ</a>'). +for triangulated output. This removes the need for +joggled input ('<a href="qh-optq.htm#QJn">QJ</a>'). Non-simplicial facets are triangulated. The facets may have zero area. Triangulated output is particularly useful for Delaunay triangulations.</p> @@ -143,41 +144,41 @@ extreme points (with roundoff): href="qh-opto.htm#n">n</a> | qhalf <a href="qh-optf.htm#Fp">Fp</a> </blockquote> -<p>Bernd Gartner published his +<p>Bernd Gartner published his <a href=http://www.inf.ethz.ch/personal/gaertner/miniball.html>Miniball</a> algorithm ["Fast and robust smallest enclosing balls", <i>Algorithms - ESA '99</i>, LNCS 1643]. It uses floating point arithmetic and a carefully designed primitive operation. It is practical to 20-D or higher, and identifies at least two points on the convex hull of the input set. Like Qhull, it is an incremental algorithm that -processes points furthest from the intermediate result and ignores +processes points furthest from the intermediate result and ignores points that are close to the intermediate result. <h2><a href="#TOC">»</a><a name="joggle">Merged facets or joggled input</a></h2> -<p>This section discusses the choice between merged facets and joggled input. +<p>This section discusses the choice between merged facets and joggled input. By default, Qhull uses merged facets to handle precision problems. With option '<a href="qh-optq.htm#QJn">QJ</a>', the input is joggled. See <a href="qh-eg.htm#joggle">examples</a> of joggled input and triangulated output. <ul> <li>Use merged facets (the default) -when you want non-simplicial output (e.g., the faces of a cube). +when you want non-simplicial output (e.g., the faces of a cube). <li>Use merged facets and triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') when you want simplicial output and coplanar facets (e.g., triangles for a Delaunay triangulation). -<li>Use joggled input ('<a href="qh-optq.htm#QJn">QJ</a>') when you need clearly-convex, -simplicial output. +<li>Use joggled input ('<a href="qh-optq.htm#QJn">QJ</a>') when you need clearly-convex, +simplicial output. </ul> <p>The choice between merged facets and joggled input depends on the application. Both run about the same speed. Joggled input may be faster if the initial joggle is sufficiently large to avoid -precision errors. +precision errors. <p>Most applications should used merged facets with triangulated output. </p> <p>Use merged facets (the -default, '<a href="qh-optc.htm#C0">C-0</a>') +default, '<a href="qh-optc.htm#C0">C-0</a>') or triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') if </p> <ul> @@ -224,31 +225,49 @@ a triangulated input. By default, <a href=qdelaun.htm>qdelaunay</a> merges regions with cocircular or cospherical input sites. If you want a simplicial triangulation use triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') or joggled -input ('<a href="qh-optq.htm#QJn">QJ</a>'). +input ('<a href="qh-optq.htm#QJn">QJ</a>'). <p>For Delaunay triangulations, triangulated output should produce good results. All points are within roundoff error of a paraboloid. If two points are nearly incident, one will be a -coplanar point. So all points are clearly separated and convex. +coplanar point. So all points are clearly separated and convex. If qhull reports deleted vertices, the triangulation may contain serious precision faults. Deleted vertices are reported in the summary ('<a href="qh-opto.htm#s">s</a>', '<a href="qh-optf.htm#Fs">Fs</a>'</p> <p>You should use option '<a href="qh-optq.htm#Qbb">Qbb</a>' with Delaunay triangulations. It scales the last coordinate and may reduce -roundoff error. It is automatically set for <a href=qdelaun.htm>qdelaunay</a>, +roundoff error. It is automatically set for <a href=qdelaun.htm>qdelaunay</a>, <a href=qvoronoi.htm>qvoronoi</a>, and option '<a href="qh-optq.htm#QJn">QJ</a>'.</p> <p>Edelsbrunner, H, <i>Geometry and Topology for Mesh Generation</i>, Cambridge University Press, 2001. -Good mathematical treatise on Delaunay triangulation and mesh generation for 2-d -and 3-d surfaces. The chapter on surface simplification is +Good mathematical treatise on Delaunay triangulation and mesh generation for 2-d +and 3-d surfaces. The chapter on surface simplification is particularly interesting. It is similar to facet merging in Qhull. <p>Veron and Leon published an algorithm for shape preserving polyhedral simplification with bounded error [<i>Computers and Graphics</i>, 22.5:565-585, 1998]. It remove nodes using front propagation and multiple remeshing. +<h2><a href="#TOC">»</a><a name="halfspace">Halfspace intersection</a></h2> + +<p> +The identity pipe for Qhull reveals some precision questions for +halfspace intersections. The identity pipe creates the convex hull of +a set of points and intersects the facets' hyperplanes. It should return the input +points, but narrow distributions may drop points while offset distributions may add +points. It may be better to normalize the input set about the origin. +For example, compare the first results with the later two results: [T. Abraham] +<blockquote> + rbox 100 s t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail +<br> + rbox 100 L1e5 t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail +<br> + rbox 100 s O10 t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail +</blockquote> + + <h2><a href="#TOC">»</a><a name="imprecise">Merged facets </a></h2> <p>Qhull detects precision @@ -403,7 +422,7 @@ a wide facet:</p> <p> <li><b>Narrow distribution</b> -- In 3-d, a narrow distribution may result in a poor -approximation. For example, if you do not use qdelaunay nor option +approximation. For example, if you do not use qdelaunay nor option '<a href="qh-optq.htm#Qbb">Qbb</a>', the furthest-site Delaunay triangulation of nearly cocircular points may produce a poor approximation: @@ -425,7 +444,7 @@ is automatically set for <a href=qdelaun.htm>qdelaunay</a> and <a href=qvoronoi. <p>Qhull generates a warning if the initial simplex is narrow. For narrow distributions, Qhull changes how it processes coplanar points -- it does not make a point coplanar until the hull is -finished. +finished. Use option '<a href="qh-optq.htm#Q10">Q10</a>' to try Qhull without special processing for narrow distributions. For example, special processing is needed for: @@ -434,11 +453,11 @@ For example, special processing is needed for: </pre> <p>You may turn off the warning message by reducing -qh_WARNnarrow in <tt>user.h</tt> or by setting option +qh_WARNnarrow in <tt>user.h</tt> or by setting option '<a href="qh-optp.htm#Pp">Pp</a>'. </p> <p>Similar problems occur for distributions with a large flat facet surrounded -with many small facet at a sharp angle to the large facet. +with many small facet at a sharp angle to the large facet. Qhull 3.1 fixes most of these problems, but a poor approximation can occur. A point may be left outside of the convex hull ('<a href="qh-optt.htm#Tv">Tv</a>'). Examples include @@ -452,10 +471,10 @@ the furthest-site Delaunay triangulation of nearly cocircular points plus the or <p> <li><b>Quadratic running time</b> -- If the output contains large, non-simplicial facets, the running time for Qhull may be quadratic in the size of the triangulated -output. For example, <tt>RBOX 1000 s W1e-13 c G2 | QHULL d</tt> is 4 times +output. For example, <tt>RBOX 1000 s W1e-13 c G2 | QHULL d</tt> is 4 times faster for 500 points. The convex hull contains two large nearly spherical facets and many nearly coplanar facets. Each new point retriangulates the spherical facet and repartitions the remaining points into all of the nearly coplanar facets. -In this case, quadratic running time is avoided if you use qdelaunay, +In this case, quadratic running time is avoided if you use qdelaunay, add option '<a href="qh-optq.htm#Qbb">Qbb</a>', or add the origin ('P0') to the input. <p> @@ -482,7 +501,7 @@ only been seen while debugging the code. <p> <li><b>Triangulated output leads to precision problems</b> -- With sufficient merging, the ridges of a non-simplicial facet may have serious topological -and geometric problems. A ridge may be between more than two +and geometric problems. A ridge may be between more than two neighboring facets. If so, their triangulation ('<a href="qh-optq.htm#Qt">Qt</a>') will fail since two facets have the same vertex set. Furthermore, a triangulated facet may have flipped orientation compared to its @@ -513,7 +532,7 @@ each distance computation. This is expensive and it conflicts with option '<a href="qh-optc.htm#Cn">C-n</a>'. <p> -<li><b>All flipped or upper Delaunay</b> -- When a lot of merging occurs for +<li><b>All flipped or upper Delaunay</b> -- When a lot of merging occurs for Delaunay triangulations, a new point may lead to no good facets. For example, try a strong convexity constraint: <pre> @@ -527,7 +546,7 @@ try a strong convexity constraint: <p>Joggled input is a simple work-around for precision problems in computational geometry ["joggle: to shake or jar slightly," Amer. Heritage Dictionary]. Other names are -<i>jostled input</i> or <i>random perturbation</i>. +<i>jostled input</i> or <i>random perturbation</i>. Qhull joggles the input by modifying each coordinate by a small random quantity. If a precision problem occurs, Qhull joggles the input with a larger @@ -705,7 +724,7 @@ increases the time and space required. Some operations are difficult to do.</p> <p>Clarkson's <a -href="http://netlib.bell-labs.com/netlib/voronoi/hull.html">hull +href="http://www.netlib.org/voronoi/hull.html">hull program</a> and Shewchuk's <a href="http://www.cs.cmu.edu/~quake/triangle.html">triangle program</a> are practical implementations of exact arithmetic.</p> @@ -754,13 +773,13 @@ page</a> for Qhull <br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> <b>To:</b> <a href="#TOC">Qhull imprecision: Table of Contents</a> diff --git a/html/qh-optc.htm b/html/qh-optc.htm index 3893f94..7a9ef15 100644 --- a/html/qh-optc.htm +++ b/html/qh-optc.htm @@ -29,7 +29,7 @@ height="100"></a> Qhull precision options</h1> This section lists the precision options for Qhull. These options are indicated by an upper-case letter followed by a number. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qh-optf.htm b/html/qh-optf.htm index fe745f0..22f45fc 100644 --- a/html/qh-optf.htm +++ b/html/qh-optf.htm @@ -9,13 +9,13 @@ <p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br> <b>Up:</b> <A href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <A href="qh-quick.htm#programs">Programs</a> -• <A href="qh-quick.htm#options">Options</a> -• <A href="qh-opto.htm#output">Output</a> -• <A href="qh-optf.htm#format">Formats</a> -• <A href="qh-optg.htm#geomview">Geomview</a> +• <A href="qh-quick.htm#options">Options</a> +• <A href="qh-opto.htm#output">Output</a> +• <A href="qh-optf.htm#format">Formats</a> +• <A href="qh-optg.htm#geomview">Geomview</a> • <A href="qh-optp.htm#print">Print</a> -• <A href="qh-optq.htm#qhull">Qhull</a> -• <A href="qh-optc.htm#prec">Precision</a> +• <A href="qh-optq.htm#qhull">Qhull</a> +• <A href="qh-optc.htm#prec">Precision</a> • <A href="qh-optt.htm#trace">Trace</a></p> <hr> <!-- Main text of document --> @@ -30,18 +30,18 @@ are indicated by 'F' followed by a letter. See <A and <A href="qh-optg.htm#geomview">Geomview</a> for other output options. </p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><A href="index.htm#TOC">»</a> <A href="qh-quick.htm#programs">Programs</a> -<a name="format">•</a> <A href="qh-quick.htm#options">Options</a> -• <A href="qh-opto.htm#output">Output</a> -• <A href="qh-optf.htm#format">Formats</a> -• <A href="qh-optg.htm#geomview">Geomview</a> +<a name="format">•</a> <A href="qh-quick.htm#options">Options</a> +• <A href="qh-opto.htm#output">Output</a> +• <A href="qh-optf.htm#format">Formats</a> +• <A href="qh-optg.htm#geomview">Geomview</a> • <A href="qh-optp.htm#print">Print</a> -• <A href="qh-optq.htm#qhull">Qhull</a> -• <A href="qh-optc.htm#prec">Precision</a> +• <A href="qh-optq.htm#qhull">Qhull</a> +• <A href="qh-optc.htm#prec">Precision</a> • <A href="qh-optt.htm#trace">Trace</a></p> <h2>Additional input & output formats</h2> @@ -56,74 +56,74 @@ may also be used.</p> <dd><b>Summary and control</b> <dt><A href="#FA">FA</a> <dd>compute total area and volume for option '<A - href="qh-opto.htm#s">s</a>' + href="qh-opto.htm#s">s</a>' <dt><A href="#FV">FV</a> <dd>print average vertex (interior point for '<A - href="qhalf.htm">qhalf</a>') + href="qhalf.htm">qhalf</a>') <dt><A href="#FQ">FQ</a> - <dd>print command for qhull and input + <dd>print command for qhull and input <dt><A href="#FO">FO</a> - <dd>print options to stderr or stdout + <dd>print options to stderr or stdout <dt><A href="#FS">FS</a> - <dd>print sizes: total area and volume + <dd>print sizes: total area and volume <dt><A href="#Fs">Fs</a> - <dd>print summary: dim, #points, total vertices and - facets, #vertices, #facets, max outer and inner plane + <dd>print summary: dim, #points, total vertices and + facets, #vertices, #facets, max outer and inner plane <dt><A href="#Fd">Fd</a> - <dd>use format for input (offset first) + <dd>use format for input (offset first) <dt><A href="#FD">FD</a> - <dd>use cdd format for normals (offset first) + <dd>use cdd format for normals (offset first) <dt><a href="#FM">FM</a> <dd>print Maple output (2-d and 3-d) <dt> <dt> <dd><b>Facets, points, and vertices</b> <dt><A href="#Fa">Fa</a> - <dd>print area for each facet + <dd>print area for each facet <dt><A href="#FC">FC</a> - <dd>print centrum for each facet + <dd>print centrum for each facet <dt><A href="#Fc">Fc</a> - <dd>print coplanar points for each facet + <dd>print coplanar points for each facet <dt><A href="#Fx">Fx</a> - <dd>print extreme points (i.e., vertices) of convex hull. + <dd>print extreme points (i.e., vertices) of convex hull. <dt><A href="#FF">FF</a> - <dd>print facets w/o ridges + <dd>print facets w/o ridges <dt><A href="#FI">FI</a> - <dd>print ID for each facet + <dd>print ID for each facet <dt><A href="#Fi">Fi</a> - <dd>print inner planes for each facet + <dd>print inner planes for each facet <dt><A href="#Fm">Fm</a> - <dd>print merge count for each facet (511 max) + <dd>print merge count for each facet (511 max) <dt><A href="#FP">FP</a> - <dd>print nearest vertex for coplanar points + <dd>print nearest vertex for coplanar points <dt><A href="#Fn">Fn</a> - <dd>print neighboring facets for each facet + <dd>print neighboring facets for each facet <dt><A href="#FN">FN</a> - <dd>print neighboring facets for each point + <dd>print neighboring facets for each point <dt><A href="#Fo">Fo</a> - <dd>print outer planes for each facet + <dd>print outer planes for each facet <dt><A href="#Ft">Ft</a> - <dd>print triangulation with added points + <dd>print triangulation with added points <dt><A href="#Fv">Fv</a> - <dd>print vertices for each facet + <dd>print vertices for each facet <dt> <dt> <dd><b>Delaunay, Voronoi, and halfspace</b> <dt><A href="#Fx">Fx</a> - <dd>print extreme input sites of Delaunay triangulation - or Voronoi diagram. + <dd>print extreme input sites of Delaunay triangulation + or Voronoi diagram. <dt><A href="#Fp">Fp</a> - <dd>print points at halfspace intersections + <dd>print points at halfspace intersections <dt><A href="#Fi2">Fi</a> - <dd>print separating hyperplanes for inner, bounded - Voronoi regions + <dd>print separating hyperplanes for inner, bounded + Voronoi regions <dt><A href="#Fo2">Fo</a> - <dd>print separating hyperplanes for outer, unbounded - Voronoi regions + <dd>print separating hyperplanes for outer, unbounded + Voronoi regions <dt><A href="#Fv2">Fv</a> - <dd>print Voronoi diagram as ridges for each input pair + <dd>print Voronoi diagram as ridges for each input pair <dt><A href="#FC">FC</a> <dd>print Voronoi vertex ("center") for each facet</dd> </dl> @@ -135,7 +135,7 @@ facet </a></h3> <p>The first line is the number of facets. The remaining lines are the area for each facet, one facet per line. See '<A - href="#FA" >FA</a>' for computing the total area and volume.</p> + href="#FA" >FA</a>' and '<A href="#FS">FS</a>' for computing the total area and volume.</p> <p>Use '<A href="qh-optp.htm#PAn">PAn</a>' for printing the n largest facets. Use option '<A href="qh-optp.htm#PFn">PFn</a>' @@ -160,21 +160,22 @@ actual value and it may be significantly less. </p> and volume for option 's' </a></h3> <p>With option 'FA', Qhull includes the total area and volume in -the summary ('<A href="qh-opto.htm#s">s</a>'). If facets are +the summary ('<A href="qh-opto.htm#s">s</a>'). Option '<A href="#FS">FS</a>' also includes the total area and volume. +If facets are merged, the area and volume are approximations. Option 'FA' is -automatically set for options '<A href="#Fa">Fa </a>', '<A +automatically set for options '<A href="#Fa">Fa</a>', '<A href="qh-optp.htm#PAn" >PAn</a>', and '<A href="qh-optp.htm#PFn">PFn</a>'. </p> <p>With '<A href="qdelaun.htm">qdelaunay</a> <A href="qh-opto.htm#s" >s</a> FA', Qhull computes the total area of the Delaunay triangulation. This equals the volume of the convex -hull of the data points. With options '<A href="qdelau_f.htm">qdelaunay Qu</a> +hull of the data points. With options '<A href="qdelau_f.htm">qdelaunay Qu</a> <A href="qh-opto.htm#s">s</a> FA', Qhull computes the total area of the furthest-site Delaunay triangulation. This equals of the total area of the Delaunay triangulation. </p> -<p>See '<A href="#Fa">Fa</a>' for further details. </p> +<p>See '<A href="#Fa">Fa</a>' for further details. Option '<A href="#FS">FS</a>' also computes the total area and volume.</p> <h3><A href="#format">»</a><a name="Fc">Fc - print coplanar points for each facet </a></h3> @@ -183,7 +184,7 @@ points for each facet </a></h3> is printed one per line. Each line is the number of coplanar points followed by the point ids. </p> -<p>By default, option 'Fc' reports coplanar points +<p>By default, option 'Fc' reports coplanar points ('<A href="qh-optq.htm#Qc">Qc</a>'). You may also use option '<A href="qh-optq.htm#Qi">Qi</a>'. Options 'Qi Fc' prints interior points while 'Qci Fc' prints both coplanar and interior @@ -216,7 +217,7 @@ data ends with an "end" line.</p> <p>For halfspaces ('<A href="qhalf.htm">qhalf</a> Fd'), the input format is the same. Each halfspace starts with its -offset. The signs of the offset and coefficients are the +offset. The signs of the offset and coefficients are the opposite of Qhull's convention. The first two lines of the input may be an interior point in '<A href="#FV">FV</a>' format.</p> @@ -310,47 +311,47 @@ output </a></h3> <p>Qhull writes a Maple file for 2-d and 3-d convex hulls, 2-d and 3-d halfspace intersections, and 2-d Delaunay triangulations. Qhull produces a 2-d -or 3-d plot. +or 3-d plot. <p><i>Warning</i>: This option has not been tested in Maple. <p>[From T. K. Abraham with help from M. R. Feinberg and N. Platinova.] -The following steps apply while working within the -Maple worksheet environment : +The following steps apply while working within the +Maple worksheet environment : <ol> -<li>Generate the data and store it as an array . For example, in 3-d, data generated +<li>Generate the data and store it as an array . For example, in 3-d, data generated in Maple is of the form : x[i],y[i],z[i] <p> -<li>Create a single variable and assign the entire array of data points to this variable. +<li>Create a single variable and assign the entire array of data points to this variable. Use the "seq" command within square brackets as shown in the following example. -(The square brackets are essential for the rest of the steps to work.) +(The square brackets are essential for the rest of the steps to work.) <p> >data:=[seq([x[i],y[i],z[i]],i=1..n)]:# here n is the number of data points -<li>Next we need to write the data to a file to be read by qhull. Before -writing the data to a file, make sure that the qhull executable files and -the data file lie in the same subdirectory. If the executable files are -stored in the "C:\qhull3.1\" subdirectory, then save the file in the same -subdirectory, say "C:\qhull3.1\datafile.txt". For the sake of integrity of -the data file , it is best to first ensure that the data file does not -exist before writing into the data file. This can be done by running a -delete command first . To write the data to the file, use the "writedata" -and the "writedata[APPEND]" commands as illustrated in the following example : +<li>Next we need to write the data to a file to be read by qhull. Before +writing the data to a file, make sure that the qhull executable files and +the data file lie in the same subdirectory. If the executable files are +stored in the "C:\qhull3.1\" subdirectory, then save the file in the same +subdirectory, say "C:\qhull3.1\datafile.txt". For the sake of integrity of +the data file , it is best to first ensure that the data file does not +exist before writing into the data file. This can be done by running a +delete command first . To write the data to the file, use the "writedata" +and the "writedata[APPEND]" commands as illustrated in the following example : <p> >system("del c:\\qhull3.1\\datafile.txt");#To erase any previous versions of the file <br>>writedata("c:\\qhull3.1\\datafile.txt ",[3, nops(data)]);#writing in qhull format <br>>writedata[APPEND]("c:\\ qhull3.1\\datafile.txt ", data);#writing the data points <li> Use the 'FM' option to produce Maple output. Store the output as a ".mpl" file. -For example, using the file we created above, we type the following (in DOS environment) +For example, using the file we created above, we type the following (in DOS environment) <p> qconvex s FM <datafile.txt >dataplot.mpl <li> -To read 3-d output in Maple, we use the 'read' command followed by +To read 3-d output in Maple, we use the 'read' command followed by a 'display3d' command. For example (in Maple environment): <p> ->with(plots): +>with (plots): <br>>read `c:\\qhull3.1\\dataplot.mpl`:#IMPORTANT - Note that the punctuation mark used is ' and NOT '. The correct punctuation mark is the one next to the key for "1" (not the punctuation mark near the enter key) <br>> qhullplot:=%: <br>> display3d(qhullplot); @@ -363,7 +364,7 @@ convex hull. <p>See <a href="qh-faq.htm#math">Is Qhull available for Maple?</a> for other URLs. - + <h3><A href="#format">»</a><a name="Fn">Fn - print neighboring facets for each facet </a></h3> @@ -373,7 +374,7 @@ followed by an index for each neighbor. The indices match the other facet output formats.</p> <p>A negative index indicates an unprinted facet due to printing -only good facets ('<A href="qh-optp.htm#Pg">Pg</a>', <A href="qdelaun.htm" >qdelaunay</a>, +only good facets ('<A href="qh-optp.htm#Pg">Pg</a>', <A href="qdelaun.htm" >qdelaunay</a>, <A href="qvoronoi.htm" >qvoronoi</a>). It is the negation of the facet's ID (option '<A href="#FI">FI</a>'). For example, negative indices are used for facets "at @@ -400,7 +401,7 @@ and higher, the facets are sorted by index. In 3-d, the facets are in adjacency order (not oriented).</p> <p>A negative index indicates an unprinted facet due to printing -only good facets (<A href="qdelaun.htm" >qdelaunay</a>, +only good facets (<A href="qdelaun.htm" >qdelaunay</a>, <A href="qvoronoi.htm" >qvoronoi</a>, '<A href="qh-optp.htm#Pdk">Pdk</a>', '<A href="qh-optp.htm#Pg">Pg</a>'). It is the negation of the facet's ID ('<A href="#FI"> FI</a>'). For example, negative @@ -414,8 +415,8 @@ option '<A href="qh-opto.htm#o">o</a>'. To convert from 'FN' to '<A href="qh-opto.htm#o" >o</a>', replace negative indices with zero and increment non-negative indices by one. </p> -<p>If you are using the <A href="qh-in.htm#library">Qhull -library</a>, option 'FN' has the side effect of reordering the +<p>If you are using the <A href="qh-code.htm#library">Qhull +library</a> or <A href="qh-code.htm#cpp">C++ interface</a>, option 'FN' has the side effect of reordering the neighbors for a vertex </p> <h3><A href="#format">»</a><a name="Fo">Fo - print outer planes @@ -509,7 +510,7 @@ original point set.</p> sites when constructing the Delaunay triangulation. Option 'FP' will list these points along with coincident points.</p> -<p>If there are many coplanar or coincident points and non-simplicial +<p>If there are many coplanar or coincident points and non-simplicial facets are triangulated ('<A href="qh-optq.htm#Qt">Qt</a>'), option 'FP' may be inefficient. It redetermines the original vertex set for each coplanar point.</p> @@ -532,23 +533,23 @@ followed by the: <li>number of vertices selected for output <li>number of facets selected for output <li>number of coplanar points for selected facets -<li>number of nonsimplicial or merged facets selected for - output -<LI>number of deleted vertices</LI> -<LI>number of triangulated facets ('<A href="qh-optq.htm#Qt">Qt</a>')</LI> +<li>number of nonsimplicial or merged facets selected for + output +<LI>number of deleted vertices</LI> +<LI>number of triangulated facets ('<A href="qh-optq.htm#Qt">Qt</a>')</LI> </ul> <p>The second line consists of the number of reals ("2") followed by the: <ul> <li>maximum offset to an outer plane -<li>minimum offset to an inner plane.</li> +<li>minimum offset to an inner plane.</li> </ul> Roundoff and joggle are included. <P></P> -<p>For Delaunay triangulations and Voronoi diagrams, the -number of deleted vertices should be zero. If greater than zero, then the +<p>For Delaunay triangulations and Voronoi diagrams, the +number of deleted vertices should be zero. If greater than zero, then the input is highly degenerate and coplanar points are not necessarily coincident points. For example, <tt>'RBOX 1000 s W1e-13 t995138628 | QHULL d Qbb'</tt> reports deleted vertices; the input is nearly cospherical.</p> @@ -567,7 +568,7 @@ or reals.</p> the halfspaces defined by each facet. It is computed from the facet area. Both area and volume are approximations for non-simplicial facets. See option '<A href="#Fa">Fa </a>' for -further notes. </p> +further notes. Option '<A href="#FA">FA </a>' also computes the total area and volume. </p> <h3><A href="#format">»</a><a name="Ft">Ft - print triangulation</a></h3> @@ -575,11 +576,11 @@ further notes. </p> facets. The output is </p> <ul> - <li>The first line is the dimension - <li>The second line is the number of points, the number - of facets, and the number of ridges. - <li>All of the input points follow, one per line. - <li>The centrums follow, one per non-simplicial facet + <li>The first line is the dimension + <li>The second line is the number of points, the number + of facets, and the number of ridges. + <li>All of the input points follow, one per line. + <li>The centrums follow, one per non-simplicial facet <li>Then the facets follow as a list of point indices preceded by the number of points. The simplices are oriented. </li> @@ -603,7 +604,7 @@ may even have a flipped orientation. Use triangulated input ('<A <p>For Delaunay triangulations with simplicial facets, the output is the same as option '<A href="qh-opto.htm#o">o</a>' without the lifted -coordinate. Since 'Ft' is invalid for merged Delaunay facets, option +coordinate. Since 'Ft' is invalid for merged Delaunay facets, option 'Ft' is not available for qdelaunay or qvoronoi. It may be used with joggled input ('<A href="qh-optq.htm#QJn" >QJ</a>') or triangulated output ('<A href="qh-optq.htm#Qt" >Qt</a>'), for example, rbox 10 c G 0.01 | qhull d QJ Ft</p> @@ -643,16 +644,16 @@ inner, bounded regions. </p> <p>Option 'Fv' does not list ridges that require more than one midpoint. For example, the Voronoi diagram of cospherical points -lists zero ridges (e.g., 'rbox 10 s | qvoronoi Fv Qz'). -Other examples are the Voronoi diagrams of a rectangular mesh +lists zero ridges (e.g., 'rbox 10 s | qvoronoi Fv Qz'). +Other examples are the Voronoi diagrams of a rectangular mesh (e.g., 'rbox 27 M1,0 | qvoronoi Fv') or a point set with -a rectangular corner (e.g., +a rectangular corner (e.g., 'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 | qvoronoi Fv'). Both cases miss unbounded rays at the corners. -To determine these ridges, surround the points with a +To determine these ridges, surround the points with a large cube (e.g., 'rbox 10 s c G2.0 | qvoronoi Fv Qz'). Please report any other cases that are missed. If you -can formally describe these cases or +can formally describe these cases or write code to handle them, please send email to <A href="mailto:qhull@qhull.org" >qhull@qhull.org</a>. </p> @@ -687,8 +688,8 @@ are sorted by index. This is the same order as option '<A href="qh-opto.htm#p" >p</a>' when it doesn't include coplanar or interior points. </p> -<p>For Delaunay triangulations, 'Fx' lists the extreme -points of the input sites (i.e., the vertices of their convex hull). The points +<p>For Delaunay triangulations, 'Fx' lists the extreme +points of the input sites (i.e., the vertices of their convex hull). The points are unordered. <!-- Navigation links --> </p> <hr> @@ -696,13 +697,13 @@ are unordered. <!-- Navigation links --> </p> <p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br> <b>Up:</b> <A href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <A href="qh-quick.htm#programs">Programs</a> -• <A href="qh-quick.htm#options">Options</a> -• <A href="qh-opto.htm#output">Output</a> -• <A href="qh-optf.htm#format">Formats</a> -• <A href="qh-optg.htm#geomview">Geomview</a> +• <A href="qh-quick.htm#options">Options</a> +• <A href="qh-opto.htm#output">Output</a> +• <A href="qh-optf.htm#format">Formats</a> +• <A href="qh-optg.htm#geomview">Geomview</a> • <A href="qh-optp.htm#print">Print</a> -• <A href="qh-optq.htm#qhull">Qhull</a> -• <A href="qh-optc.htm#prec">Precision</a> +• <A href="qh-optq.htm#qhull">Qhull</a> +• <A href="qh-optc.htm#prec">Precision</a> • <A href="qh-optt.htm#trace">Trace</a></p><!-- GC common information --> <hr> @@ -712,8 +713,8 @@ 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 top +Created: +Sept. 25, 1995 --- <!-- hhmts start -->Last modified: see top <!-- hhmts end --> </p> </body> </html> diff --git a/html/qh-optg.htm b/html/qh-optg.htm index 3db0fc6..680489b 100644 --- a/html/qh-optg.htm +++ b/html/qh-optg.htm @@ -33,7 +33,7 @@ indicated by 'G' followed by a letter. See and <a href="qh-optf.htm#format">Format</a> for other output options. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qh-opto.htm b/html/qh-opto.htm index 0ec45f1..3004f25 100644 --- a/html/qh-opto.htm +++ b/html/qh-opto.htm @@ -33,7 +33,7 @@ href="qh-optp.htm#print">Print</a>, and <a href="qh-optg.htm#geomview">Geomview</a> for other output options. </p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> @@ -87,7 +87,7 @@ Other outputs may be specified as follows. </p> <h3><a href="#output">»</a><a name="f">f - print all fields of all facets </a></h3> -<p>Print <a href=../src/qhull.h#facetT>all fields</a> of all facets. +<p>Print <a href=../src/qhulllib.h#facetT>all fields</a> of all facets. The facet is the primary <a href=index.htm#structure>data structure</a> for Qhull. @@ -95,7 +95,8 @@ Qhull. debugging. Most of the fields are available via the '<a href="qh-optf.htm#format">F</a>' options. If you need specialized information from Qhull, you can use the <a -href="qh-in.htm#library">Qhull library</a>.</p> +href="qh-code.htm#library">Qhull library</a> or <a +href="qh-code.htm#cpp">C++ interface</a>.</p> <p>Use the '<a href="qh-optf.htm#FF">FF</a>' option to print the facets but not the ridges. </p> @@ -114,7 +115,8 @@ vertex prior to the vertices for each facet. </p> <p>Simplicial facets (e.g., triangles in 3-d) consist of <i>d</i> vertices. Non-simplicial facets in 3-d consist of 4 or more -vertices. For example, a facet of a cube consists of 4 vertices.</p> +vertices. For example, a facet of a cube consists of 4 vertices. +Use option '<a href="qh-optq.htm#Qt">Qt</a>' to triangulate non-simplicial facets.</p> <p>For 4-d and higher convex hulls and 3-d and higher Delaunay triangulations, <i>d</i> vertices are listed for all facets. A @@ -299,7 +301,7 @@ simplicial. </p> <p>Qhull starts counting CPU seconds after it has read and projected the input points. It stops counting before producing output. In the code, CPU seconds measures the execution time of -function qhull() in <tt>qhull.c</tt>. If the number of CPU +function qhull() in <tt>qhulllib.c</tt>. If the number of CPU seconds is clearly wrong, check qh_SECticks in <tt>user.h</tt>. </p> <p>The last two figures measure the maximum distance from a point diff --git a/html/qh-optp.htm b/html/qh-optp.htm index 8849da2..8f5891f 100644 --- a/html/qh-optp.htm +++ b/html/qh-optp.htm @@ -32,7 +32,7 @@ indicated by 'P' followed by a letter. See and <a href="qh-optf.htm#format">Format</a> for other output options. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qh-optq.htm b/html/qh-optq.htm index 331daa0..3d02d6d 100644 --- a/html/qh-optq.htm +++ b/html/qh-optq.htm @@ -29,7 +29,7 @@ height="100"></a> Qhull control options (Q)</h1> <p>This section lists the control options for Qhull. These options are indicated by 'Q' followed by a letter. </p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qh-optt.htm b/html/qh-optt.htm index 15d8c55..7efc749 100644 --- a/html/qh-optt.htm +++ b/html/qh-optt.htm @@ -29,7 +29,7 @@ height="100"></a> Qhull trace options (T)</h1> This section lists the trace options for Qhull. These options are indicated by 'T' followed by a letter. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qh-quick.htm b/html/qh-quick.htm index 29d9d0d..2ddbfde 100644 --- a/html/qh-quick.htm +++ b/html/qh-quick.htm @@ -11,15 +11,15 @@ page for Qhull</a> <br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a> <br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a> <br> -<b>To:</b> <a href="qh-in.htm#TOC">Qhull internals</a><br> +<b>To:</b> <a href="qh-code.htm#TOC">Qhull internals</a><br> <b>To:</b> <a href="../src/index.htm">Qhull functions</a>, macros, and data structures<br> <b>To:</b> <a href="../src/index.htm#TOC">Qhull files</a><br> <b>To:</b> <a href="../src/qh-geom.htm">Geom</a> • <a href="../src/qh-globa.htm">Global</a> @@ -38,20 +38,20 @@ height="100"></a> Qhull quick reference</h1> This section lists all programs and options in Qhull. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <p> <a name="programs"> </a> <hr> <b>Qhull programs</b> <p><a href="#TOC">»</a> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a></p> <dl> @@ -60,29 +60,29 @@ This section lists all programs and options in Qhull. href="qconvex.htm#input">in</a>put • <a href="qconvex.htm#outputs">ou</a>tputs • <a href="qconvex.htm#controls">co</a>ntrols • <a - href="qconvex.htm#graphics">gr</a>aphics • <a - href="qconvex.htm#notes">no</a>tes • <a + href="qconvex.htm#graphics">gr</a>aphics • <a + href="qconvex.htm#notes">no</a>tes • <a href="qconvex.htm#conventions">co</a>nventions • <a href="qconvex.htm#options">op</a>tions</dd> <dt> </dt> <dt><a href="qdelaun.htm">qdelaunay</a> -- Delaunay triangulation</dt> <dd><a href="qdelaun.htm#synopsis">sy</a>nopsis • <a href="qdelaun.htm#input">in</a>put • <a - href="qdelaun.htm#outputs">ou</a>tputs • <a + href="qdelaun.htm#outputs">ou</a>tputs • <a href="qdelaun.htm#controls">co</a>ntrols • <a href="qdelaun.htm#graphics">gr</a>aphics • <a href="qdelaun.htm#notes">no</a>tes • <a - href="qdelaun.htm#conventions">co</a>nventions • <a + href="qdelaun.htm#conventions">co</a>nventions • <a href="qdelaun.htm#options">op</a>tions</dd> <dt> </dt> <dt><a href="qdelau_f.htm">qdelaunay Qu</a> -- furthest-site Delaunay triangulation</dt> <dd><a href="qdelau_f.htm#synopsis">sy</a>nopsis • <a href="qdelau_f.htm#input">in</a>put • <a - href="qdelau_f.htm#outputs">ou</a>tputs • <a + href="qdelau_f.htm#outputs">ou</a>tputs • <a href="qdelau_f.htm#controls">co</a>ntrols • <a href="qdelau_f.htm#graphics">gr</a>aphics • <a href="qdelau_f.htm#notes">no</a>tes • <a - href="qdelau_f.htm#conventions">co</a>nventions • <a + href="qdelau_f.htm#conventions">co</a>nventions • <a href="qdelau_f.htm#options">op</a>tions</dd> <dt> </dt> <dt><a href="qhalf.htm">qhalf</a> -- halfspace intersection about a point</dt> @@ -90,8 +90,8 @@ This section lists all programs and options in Qhull. href="qhalf.htm#input">in</a>put • <a href="qhalf.htm#outputs">ou</a>tputs • <a href="qhalf.htm#controls">co</a>ntrols • <a - href="qhalf.htm#graphics">gr</a>aphics • <a - href="qhalf.htm#notes">no</a>tes • <a + href="qhalf.htm#graphics">gr</a>aphics • <a + href="qhalf.htm#notes">no</a>tes • <a href="qhalf.htm#conventions">co</a>nventions • <a href="qhalf.htm#options">op</a>tions</dd> <dt> </dt> @@ -102,24 +102,24 @@ This section lists all programs and options in Qhull. <a href="qvoronoi.htm#controls">co</a>ntrols • <a href="qvoronoi.htm#graphics">gr</a>aphics • <a href="qvoronoi.htm#notes">no</a>tes • <a - href="qvoronoi.htm#conventions">co</a>nventions • <a + href="qvoronoi.htm#conventions">co</a>nventions • <a href="qvoronoi.htm#options">op</a>tions</dd> <dt> </dt> <dt><a href="qvoron_f.htm">qvoronoi Qu</a> -- furthest-site Voronoi diagram</dt> <dd><a href="qvoron_f.htm#synopsis">sy</a>nopsis • <a href="qvoron_f.htm#input">in</a>put • <a - href="qvoron_f.htm#outputs">ou</a>tputs • <a + href="qvoron_f.htm#outputs">ou</a>tputs • <a href="qvoron_f.htm#controls">co</a>ntrols • <a href="qvoron_f.htm#graphics">gr</a>aphics • <a href="qvoron_f.htm#notes">no</a>tes • <a - href="qvoron_f.htm#conventions">co</a>nventions • <a + href="qvoron_f.htm#conventions">co</a>nventions • <a href="qvoron_f.htm#options">op</a>tions</dd> <dt> </dt> <dt><a href="rbox.htm">rbox</a> -- generate point distributions for qhull</dt> <dd><a href="rbox.htm#synopsis">sy</a>nopsis • <a href="rbox.htm#outputs">ou</a>tputs • <a href="rbox.htm#examples">ex</a>amples • <a - href="rbox.htm#notes">no</a>tes • <a + href="rbox.htm#notes">no</a>tes • <a href="rbox.htm#options">op</a>tions</dd> <dt> </dt> <dt><a href="qhull.htm">qhull</a> -- convex hull and related structures</dt> @@ -134,13 +134,13 @@ This section lists all programs and options in Qhull. <b>Qhull options</b> <p><a href="#TOC">»</a> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a></p> <p><table> @@ -220,7 +220,7 @@ Fxtremes <td><nobr>'<a href=qh-optp.htm#PAn>PAn</a>' PArea-keep </nobr></td><td><nobr>'<a href=qh-optp.htm#Pdk>Pdk:n</a>' -Pdrop_low +Pdrop_low </nobr></td><td><nobr>'<a href=qh-optp.htm#PDk>PDk:n</a>' Pdrop_high </nobr></td><td><nobr>'<a href=qh-optp.htm#Pg>Pg</a>' @@ -461,15 +461,15 @@ Q11_trinormals page for Qhull</a> <br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a> <br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="qh-in.htm#TOC">Qhull internals</a><br> +<b>To:</b> <a href="qh-code.htm#TOC">Qhull internals</a><br> <b>To:</b> <a href="../src/index.htm">Qhull functions</a>, macros, and data structures<br> <b>To:</b> <a href="../src/index.htm#TOC">Qhull files</a><br> <b>To:</b> <a href="../src/qh-geom.htm">Geom</a> • <a href="../src/qh-globa.htm">Global</a> diff --git a/html/qhalf.htm b/html/qhalf.htm index 34ab9c7..d0036b7 100644 --- a/html/qhalf.htm +++ b/html/qhalf.htm @@ -54,7 +54,7 @@ programming. </p> href="qh-optf.htm#Fp">Fp</a></dt> <dd>Print the intersection of the facets of a cube and a diamond. There are 24 facets and 14 intersection points. Four facets define each diamond - vertext. Six facets define each cube vertex. + vertex. Six facets define each cube vertex. </dd> <dt><p><b>Example:</b> rbox c d G0.55 | qconvex <a href="qh-optf.htm#FQ">FQ</a> <a href="qh-optf.htm#FV">FV</a> @@ -103,7 +103,7 @@ in 5-d and higher. It disables the following Qhull Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0,etc</i>. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <h3><a href="#TOP">»</a><a name="synopsis">qhalf synopsis</a></h3> @@ -382,6 +382,8 @@ href="qh-eg.htm#half">Halfspace examples</a>.</p> <h3><a href="#TOP">»</a><a name="notes">qhalf notes</a></h3> <blockquote> +<p>See <a href="qh-impre.htm#halfspace">halfspace intersection</a> for precision issues related to qhalf.</p> + <p>If you do not know an interior point for the halfspaces, use linear programming to find one. Assume, <em>n</em> halfspaces defined by: <em>aj*x1+bj*x2+cj*x3+dj>=0, j=1..n</em>. Perform @@ -592,3 +594,4 @@ Home Page </i></p> Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p> </body> </html> + diff --git a/html/qhull-cpp.xml b/html/qhull-cpp.xml new file mode 100644 index 0000000..0cd5cae --- /dev/null +++ b/html/qhull-cpp.xml @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="utf-8"?> +<?xml-stylesheet type="text/xsl" href="/road/road-faq/xsl/road-faq.xsl"?> + +<rf:topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://schemas.roadintranet.org/road-faq-1 /road/road-faq/xsl/road-faq.xsd" + xmlns:rf="http://schemas.roadintranet.org/road-faq-1" + title=" C++ interface to Qhull" + file="qhull-cpp.xml" + fileid="$Id: //product/qhull/main/rel/html/qhull-cpp.xml#21 $$Change: 1083 $" + fileChange="$DateTime: 2009/11/18 22:43:17 $$Author: bbarber $"> + <div><h4>Qhull C++ -- C++ interface to Qhull</h4></div> + <rf:copyright> + <a href="../cpp/COPYING.txt">Copyright</a> (c) 2009-2009, C. Bradford Barber + </rf:copyright> + <rf:section id="cpp-cpp-links" title="Useful Links for Qhull C++"> + <div> + <p> This + document records + + Please send comments and suggestions to <a + href="mailto:bradb@shore.net">bradb@shore.net</a> + </p> + </div> + <div class="twocol"> + <div class="col leftcol"> + Help + <ul><li> + C++ In a Nutshell [<a href="#liscR_2003">liscR_2003</a>, + <a href="http://www.tempest-sw.com/cpp/draft/">online</a>] -- + Concise and complete description of C++. + </li><li> + <a href="http://codeidol.com/">CodeIdol</a> -- free, on-line books on coding and IT + </li><li> + </li></ul> + </div> + <div class="col rightcol"> + C++ usage + <ul><li> + </li><li> + </li></ul> + </div> + </div> + <div> + . <!-- clear the two column display --> + </div> + + </rf:section> + <rf:section id="qhull-api" title="Qhull's collection classes"> + + <rf:item id="collection-api" title="API for Qhull collections" date="Feb 2009" author="bbarber"> + Qhull's collection APIs are modeled on Qt's collection API (QList, QVector, QHash). They support STL and Qt programming. + + Some of Qhull's collection classes derive from STL classes. If so, + please avoid additional STL functions and operators added by inheritance. + These collection classes may be rewritten to derive from Qt classes instead. + +See <rf:iref item="cpp-collection-api"/>. + + Qhull's collection API (where applicable). For documentation, see Qt's QList, QMap, QListIterator, QMapIterator, QMutableListIterator, and QMutableMapIterator + <ul><li> + STL types [list, qlinkedlist, qlist, qvector, vector] -- const_iterator, iterator + </li><li> + STL types describing iterators [list, qlinkedlist, qlist, qvector, vector] -- const_pointer, const_reference, difference_type, + pointer, reference, size_type, value_type. + Pointer and reference types not defined if unavailable (not needed for <algorithm>) + </li><li> + const_iterator, iterator types -- difference_type, iterator_category, pointer, reference, value_type + </li><li> + Qt types [qlinkedlist, qlist, qvector] -- ConstIterator, Iterator, QhullclassIterator, MutableQhullclassIterator. + Qt's foreach requires const_iterator. + </li><li> + Types for sets/maps [hash_map, QHash] -- key_compare, key_type, mapped_type + </li><li> + Constructor -- default constructor, copy constructor, assignment operator, destructor + </li><li> + Conversion -- to/from/as corresponding C, STL, and Qt constructs. Include toQList and toStdVector (may be filtered, e.g., QhullFacetSet). + Do not define fromStdList and fromQList if container is not reference counted (i.e., acts like a value) + </li><li> + Get/set -- configuration options for class + </li><li> + STL-style iterator - begin, constBegin, constEnd, end, key, value, =, *, [], ->, ++, --, +, -, ==, !=, <, + <=, >, >=, const_iterator(iterator), iterator COMPARE const_iterator. + An iterator is an abstraction of a pointer. It is not aware of its container. + </li><li> + Java-style iterator [qiterator.h] - countRemaining, findNext, findPrevious, hasNext, hasPrevious, next, peekNext, peekPrevious, previous, toBack, toFront, = Coordinates + </li><li> + Mutable Java-style iterator adds - insert, remove, setValue, value + </li><li> + Element access -- back, first, front, last + </li><li> + Element access w/ index -- [], at (const& only), constData, data, mid, value + </li><li> + Read-only - (int)count, empty, isEmpty, (size_t)size. Count() and size() may be filtered. If so, they may be zero when !empty(). + </li><li> + Read-only for sets/maps - capacity, key, keys, reserve, resize, values + </li><li> + Operator - ==, !=, +, +=, << + </li><li> + Read-write -- append, clear, erase, insert, move, prepend, pop_back, pop_front, push_back, push_front, removeAll, removeAt, removeFirst, removeLast, replace, + swap, takeAt, takeFirst, takeLast + </li><li> + Read-write for sets/maps -- insertMulti, squeeze, take, unite + </li><li> + Search -- contains(const T &), count(const T &), indexOf, lastIndexOf + </li><li> + Search for sets/maps -- constFind, lowerBound, upperBound + </li><li> + Stream I/O -- stream << + </li></ul> + + STL list and vector -- For unfiltered access to each element. + <ul><li> + <a href="http://stdcxx.apache.org/doc/stdlibug/16-3.html">Apache: Creating your own containers</a> -- requirements for STL containers. Iterators should define the types from 'iterator_traits'. + </li><li> + STL types -- allocator_type, const_iterator, const_pointer, const_reference, const_reverse_iterator, difference_type, iterator, iterator_category, pointer, reference, reverse_iterator, size_type, value_type + </li><li> + STL constructors -- MyType(), MyType(count), MyType(count, value), MyType(first, last), + MyType(MyType&), + </li><li> + STL getter/setters -- at (random_access only), back, begin, capacity, end, front, rbegin, rend, size, max_size + </li><li> + STL predicates -- empty + </li><li> + STL iterator types -- const_pointer, const_reference, difference_type, iterator_category, pointer, reference, value_type + </li><li> + STL iterator operators -- *, -<, ++, --, +=, -=, +, -, [], ==, !=, <, >, >=, <= + </li><li> + STL operators -- =, [] (random_access only), ==, !=, <, >, <=, >= + </li><li> + STL modifiers -- assign, clear, erase, insert, pop_back, push_back, reserve, resize, swap + </li><li> + </li></ul> + + Qt Qlist -- For unfiltered access to each element + <ul><li> + </li><li> + Additional Qt types -- ConstIterator, Iterator, QListIterator, QMutableListIterator + </li><li> + Additional Qt get/set -- constBegin, constEnd, count, first, last, value (random_access only) + </li><li> + Additional Qt predicates -- isEmpty + </li><li> + Additional Qt -- mid (random_access only) + </li><li> + Additional Qt search -- contains, count(T&), indexOf (random_access only), lastIndeOf (random_access only) + </li><li> + Additional Qt modifiers -- append, insert(index,value) (random_access only), move (random_access only), pop_front, prepend, push_front, removeAll, removeAt (random_access only), removeFirst, removeLast, replace, swap by index, takeAt, takeFirst, takeLast + </li><li> + Additional Qt operators -- +, <<, +=, + stream << and >> + </li><li> + Unsupported types by Qt -- allocator_type, const_reverse_iterator, reverse_iterator + </li><li> + Unsupported accessors by Qt -- max_size, rbegin, rend + </li><li> + Unsupported constructors by Qt -- multi-value constructors + </li><li> + unsupported modifiers by Qt -- assign, muli-value inserts, STL's swaps + </li><li> + </li></ul> + + STL map and Qt QMap. These use nearly the same API as list and vector classes. They add the following. + <ul><li> + STL types -- key_compare, key_type, mapped_type + </li><li> + STL search -- equal_range, find, lower_bound, upper_bound + </li><li> + Qt removes -- equal_range, key_compare + </li><li> + Qt renames -- lowerBound, upperBound + </li><li> + Qt adds -- constFind, insertMulti, key, keys, take, uniqueKeys, unite, values + </li><li> + Not applicable to map and QMap -- at, back, pop_back, pop_front, push_back, push_front, swap + </li><li> + Not applicable to QMap -- append, first, last, lastIndexOf, mid, move, prepend, removeAll, removeAt, removeFirst, removeLast, replace, squeeze, takeAt, takeFirst, takeLast + </li><li> + Not applicable to map -- assign + </li></ul> + + Qt QHash. STL extensions provide similar classes, e.g., Microsoft's stdext::hash_set. THey are nearly the same as QMap + <ul><li> + </li><li> + </li><li> + Not applicable to Qhash -- lowerBound, unite, upperBound, + </li><li> + Qt adds -- squeeze + </li></ul> + </rf:item> + <rf:item id="class-api" title="API for Qhull collections" date="Feb 2009" author="bbarber"> + <ul><li> + check... -- Throw error on failure + </li><li> + parameter order -- qhRunId, dimension, coordinates, count. + </li><li> + toClass -- Convert into a Class object (makes a deep copy) + </li><li> + qRunId -- Requires Qh installed. Some routines allow 0 for limited info (e.g., operator<<) + </li><li> + Disable methods in derived classes -- If the default constructor, copy constructor, or copy assignment is disabled, it should be also disabled in derived classes (better error messages). + </li><li> + Constructor order -- default constructor, other constructors, copy constructor, copy assignment, destructor + </li></ul> + </rf:item> + </rf:section> + <rf:section id="cpp-ref" title="C++ References" order="sorted"> + <rf:item id="bulkD_2000" title="[bulkD_2000] Efficient C++: Performance Programming + Techniques" date="Dec 2008" author="bbarber"> + <p>Bulka, Mayhew, Addison-Wesley, 2000, ISBN 0-201-37950-3</p> + <p>Efficient C++ programming with timing comparisons.</p> + </rf:item> + </rf:section> +</rf:topic> diff --git a/html/qhull.htm b/html/qhull.htm index affad50..b25a569 100644 --- a/html/qhull.htm +++ b/html/qhull.htm @@ -116,7 +116,7 @@ hull contains non-simplicial facets (e.g., a hypercube). See are there extra points in a 4-d or higher convex hull?</a><br> </p> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> diff --git a/html/qhull.man b/html/qhull.man index a65d082..5b0f723 100644 --- a/html/qhull.man +++ b/html/qhull.man @@ -57,7 +57,7 @@ example: - installation: README.txt - see also: COPYING.txt, REGISTER.txt, Changes.txt - WWW: <http://www.qhull.org> - - CVS: <http://savannah.gnu.org/projects/qhull/> + - CVS: <http://savannah.nongnu.org/projects/qhull/> - 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> @@ -964,9 +964,9 @@ rbox(1) Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The Quickhull Algorithm for Convex Hulls," ACM -Trans. on Mathematical Software, Dec. 1996. -http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/ -http://citeseer.nj.nec.com/83502.html +Trans. on Mathematical 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.54.6345 Clarkson, K.L., K. Mehlhorn, and R. Seidel, "Four results on randomized incremental construction," Computational Geometry: Theory and Applications, @@ -994,9 +994,9 @@ Geometry, Springer-Verlag, New York, 1985. A special thanks to Albert Marden, Victor Milenkovic, the Geometry Center, Harvard University, and Endocardial Solutions, Inc. for supporting this work. -The software was developed under National Science Foundation grants -NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. David Dobkin guided -the original work at Princeton University. +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 +guided the original work at Princeton University. If you find it useful, please let us know. The Geometry Center is supported by grant DMS-8920161 from the National diff --git a/html/qhull.txt b/html/qhull.txt index f3b2f88..4ad3299 100644 --- a/html/qhull.txt +++ b/html/qhull.txt @@ -46,7 +46,7 @@ SYNOPSIS - installation: README.txt - see also: COPYING.txt, REGISTER.txt, Changes.txt - WWW: <http://www.qhull.org> - - CVS: <http://savannah.gnu.org/projects/qhull/> + - CVS: <http://savannah.nongnu.org/projects/qhull/> - 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> @@ -1158,9 +1158,9 @@ SEE ALSO Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The Quickhull Algorithm for Convex Hulls," ACM Trans. on Math- - ematical Software, Dec. 1996. - http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/ - http://citeseer.nj.nec.com/83502.html + 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.54.6345 Clarkson, K.L., K. Mehlhorn, and R. Seidel, "Four results @@ -1190,8 +1190,8 @@ ACKNOWLEDGEMENTS Geometry Center, Harvard University, and Endocardial Solu- tions, Inc. for supporting this work. - The software was developed under National Science Founda- - tion grants NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. + 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 @@ -1204,15 +1204,13 @@ Geometry Center 2003/12/30 18 qhull(1) qhull(1) - David Dobkin guided the original work at Princeton Univer- - sity. If you find it useful, please let us know. + guided the original work at Princeton University. - The Geometry Center is supported by grant DMS-8920161 from - the National Science Foundation, by grant DOE/DE- - FG02-92ER25137 from the Department of Energy, by the Uni- - versity of Minnesota, and by Minnesota Technology, Inc. + The Geometry Center is 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 at http://www.qhull.org + Qhull is available from http://www.qhull.org diff --git a/html/qvoron_f.htm b/html/qvoron_f.htm index 8aa3ea2..712716f 100644 --- a/html/qvoron_f.htm +++ b/html/qvoron_f.htm @@ -93,7 +93,7 @@ in 4-d and higher. It disables the following Qhull QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V Fa FA FC Fp FS Ft FV Gt Q0,etc</i>. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> <hr> <h3><a href="#TOP">»</a><a name="synopsis">furthest-site qvoronoi synopsis</a></h3> diff --git a/html/qvoronoi.htm b/html/qvoronoi.htm index 5f50e87..88b94a4 100644 --- a/html/qvoronoi.htm +++ b/html/qvoronoi.htm @@ -7,29 +7,29 @@ <body> <!-- Navigation links --> -<a name="TOP"><b>Up</b></a><b>:</b> +<a name="TOP"><b>Up</b></a><b>:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="#synopsis">sy</a>nopsis -• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs -• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics -• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions +<b>To:</b> <a href="#synopsis">sy</a>nopsis +• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs +• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics +• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions • <a href="#options">op</a>tions <hr> <!-- Main text of document --> <h1><a -href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img -src="qh--dt.gif" alt="[delaunay]" align="middle" width="100" +href="http://www.archinect.com/gallery/displayimage.php?pos=-4658"><img +src="normal_voronoi_knauss_oesterle.jpg" alt="[voronoi]" align="middle" height="100"></a>qvoronoi -- Voronoi diagram</h1> <p>The Voronoi diagram is the nearest-neighbor map for a set of @@ -51,7 +51,7 @@ dual of the <a href=qdelaun.htm>Delaunay triangulation</a>. </p> indicates unbounded regions.</dd> <dt> </dt> - <dt><b>Example:</b> rbox r y c G0.1 D2 | qvoronoi + <dt><b>Example:</b> rbox r y c G0.1 D2 | qvoronoi <a href="qh-opto.htm#s">s</a> <a href="qh-opto.htm#o">o</a> <a href="qh-optt.htm#TO">TO result</a></dt> @@ -76,7 +76,7 @@ dual of the <a href=qdelaun.htm>Delaunay triangulation</a>. </p> <dt> </dt> <dt><b>Example:</b> rbox r y c G0.1 D2 | qvoronoi <a href="qh-optf.htm#Fi2">Fi</a></dt> - <dd>Print the bounded, separating hyperplanes for the 2-d Voronoi diagram of a + <dd>Print the bounded, separating hyperplanes for the 2-d Voronoi diagram of a triangle and a small square. Note the four hyperplanes (i.e., lines) for Voronoi vertex "8". It is at the origin. @@ -90,10 +90,10 @@ vertex is the circumcenter of a facet of the Delaunay triangulation. Each Voronoi region corresponds to a vertex (i.e., input site) of the Delaunay triangulation. </p> -<p>Qhull outputs the Voronoi vertices for each Voronoi region. With +<p>Qhull outputs the Voronoi vertices for each Voronoi region. With option '<a href="qh-optf.htm#Fv2">Fv</a>', it lists all ridges of the Voronoi diagram with the corresponding -pairs of input sites. With +pairs of input sites. With options '<a href="qh-optf.htm#Fi2">Fi</a>' and '<a href="qh-optf.htm#Fo2">Fo</a>', it lists the bounded and unbounded separating hyperplanes. You can also output a single Voronoi region @@ -108,14 +108,16 @@ unexpected results. Cocircular and cospherical input sites will produce duplicate or nearly duplicate Voronoi vertices. See also <a href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p> -<p>The 'qvonoroi' program is equivalent to +<p>The 'qvonoroi' program is equivalent to '<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a>' in 2-d to 3-d, and -'<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>' +'<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>' in 4-d and higher. It disables the following Qhull -<a href=qh-quick.htm#options>options</a>: <i>d n v Qbb QbB Qf Qg Qm +<a href=qh-quick.htm#options>options</a>: <i>d n v Qbb QbB Qf Qg Qm Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0,etc</i>. -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2008 The Geometry Center, Minneapolis MN</b></p> + +<p>Voronoi image by KOOK Architecture, Silvan Oesterle and Michael Knauss. <hr> <h3><a href="#TOP">»</a><a name="synopsis">qvoronoi synopsis</a></h3> @@ -156,21 +158,21 @@ rbox c P0 D2 | qvoronoi s Fv QV0 <blockquote> The input data on <tt>stdin</tt> consists of: <ul> - <li>dimension + <li>dimension <li>number of points</li> <li>point coordinates</li> </ul> <p>Use I/O redirection (e.g., qvoronoi < data.txt), a pipe (e.g., rbox 10 | qvoronoi), -or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qvoronoi TI data.txt). +or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qvoronoi TI data.txt). <p>For example, this is four cocircular points inside a square. Their Voronoi diagram has nine vertices and eight regions. Notice the Voronoi vertex -at the origin, and the Voronoi vertices (on each axis) for the four +at the origin, and the Voronoi vertices (on each axis) for the four sides of the square. <p> <blockquote> -<tt>rbox s 4 W0 c G1 D2 > data</tt> +<tt>rbox s 4 W0 c G1 D2 > data</tt> <blockquote><pre> 2 RBOX s 4 W0 c D2 8 @@ -235,15 +237,15 @@ outputs</a></h3> <dt><a href="qh-optf.htm#Fn">Fn</a></dt> <dd>list the neighboring Voronoi vertices for each Voronoi vertex. The first line is the number of Voronoi vertices. Each - remaining line starts with the number of neighboring vertices. - Negative vertices (e.g., <em>-1</em>) indicate vertices + remaining line starts with the number of neighboring vertices. + Negative vertices (e.g., <em>-1</em>) indicate vertices outside of the Voronoi diagram. - In the circle-in-box example, the + In the circle-in-box example, the Voronoi vertex at the origin has four neighbors.</dd> <dt><a href="qh-optf.htm#FN">FN</a></dt> - <dd>list the Voronoi vertices for each Voronoi region. The first line is + <dd>list the Voronoi vertices for each Voronoi region. The first line is the number of Voronoi regions. Each remaining line starts with the - number of Voronoi vertices. Negative indices (e.g., <em>-1</em>) indicate vertices + number of Voronoi vertices. Negative indices (e.g., <em>-1</em>) indicate vertices outside of the Voronoi diagram. In the circle-in-box example, the four bounded regions are defined by four Voronoi vertices.</dd> @@ -252,7 +254,7 @@ outputs</a></h3> <dt> </dt> <dd><b>Voronoi regions</b></dd> <dt><a href="qh-opto.htm#o">o</a></dt> - <dd>print the Voronoi regions in OFF format. The first line is the + <dd>print the Voronoi regions in OFF format. The first line is the dimension. The second line is the number of vertices, the number of input sites, and "1". The third line represents the vertex-at-infinity. Its coordinates are "-10.101". The next lines are the coordinates @@ -276,7 +278,7 @@ statistics to stderr. </dd> <dd>print separating hyperplanes for outer, unbounded Voronoi regions. The first number is the number of separating hyperplanes. Each remaining line starts with <i>3+dim</i>. The - next two numbers are adjacent input sites on the convex hull. The + next two numbers are adjacent input sites on the convex hull. The next <i>dim</i> numbers are the coefficients of the separating hyperplane. The last number is its offset. Use '<a href="qh-optt.htm#Tv">Tv</a>' to verify that the @@ -290,7 +292,7 @@ statistics to stderr,</dd> first line is the number of ridges. Each remaining line starts with two plus the number of Voronoi vertices in the ridge. The next two numbers are two adjacent input sites. The remaining numbers list - the Voronoi vertices. As with option 'o', a <em>0</em> indicates + the Voronoi vertices. As with option 'o', a <em>0</em> indicates the vertex-at-infinity and an unbounded, separating hyperplane. The perpendicular bisector (separating hyperplane) @@ -299,7 +301,7 @@ statistics to stderr,</dd> is unbounded.</dd> <dt><a href="qh-optf.htm#Fc">Fc</a></dt> <dd>list coincident input sites for each Voronoi vertex. - The first line is the number of vertices. The remaining lines start with + The first line is the number of vertices. The remaining lines start with the number of coincident sites and deleted vertices. Deleted vertices indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). A coincident site is assigned to one Voronoi @@ -307,11 +309,11 @@ statistics to stderr,</dd> coincident sites.</dd> <dt><a href="qh-optf.htm#FP">FP</a></dt> <dd>print coincident input sites with distance to - nearest site (i.e., vertex). The first line is the + nearest site (i.e., vertex). The first line is the number of coincident sites. Each remaining line starts with the point ID of an input site, followed by the point ID of a coincident point, its vertex, and distance. Includes deleted vertices which - indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). + indicate highly degenerate input (see'<A href="qh-optf.htm#Fs">Fs</a>'). Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'FP'; the joggle will separate coincident sites.</dd> <dt> </dt> @@ -369,7 +371,7 @@ controls</a></h3> <dd>include upper and lower facets in the output. Set <em>k</em> to the last dimension (e.g., 'PD2:1' for 2-d inputs). </dd> <dt><a href="qh-opto.htm#f">f </a></dt> - <dd>facet dump. Print the data structure for each facet (i.e., + <dd>facet dump. Print the data structure for each facet (i.e., Voronoi vertex).</dd> </dl> @@ -396,7 +398,7 @@ view the Voronoi region for site 3 in Geomview, execute</p> for input site 3. The <tt>qconvex</tt> command computes their convex hull. This is the Voronoi region for input site 3. Its hyperplane normals (qconvex 'n') are the same as the separating hyperplanes -from options '<a href="qh-optf.htm#Fi">Fi</a>' +from options '<a href="qh-optf.htm#Fi">Fi</a>' and '<a href="qh-optf.htm#Fo">Fo</a>' (up to roundoff error). <p>See the <a href="qh-eg.htm#delaunay">Delaunay and Voronoi @@ -429,8 +431,8 @@ output is </p> <blockquote> <pre>3 2 9 1 --10.101 -10.101 -10.101 - 0 0 0 +-10.101 -10.101 -10.101 + 0 0 0 2 0 1 2 0 1 2 0 1 @@ -646,18 +648,18 @@ Print options: <p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br> <b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br> <b>To:</b> <a href="qh-quick.htm#programs">Programs</a> -• <a href="qh-quick.htm#options">Options</a> -• <a href="qh-opto.htm#output">Output</a> -• <a href="qh-optf.htm#format">Formats</a> -• <a href="qh-optg.htm#geomview">Geomview</a> +• <a href="qh-quick.htm#options">Options</a> +• <a href="qh-opto.htm#output">Output</a> +• <a href="qh-optf.htm#format">Formats</a> +• <a href="qh-optg.htm#geomview">Geomview</a> • <a href="qh-optp.htm#print">Print</a> -• <a href="qh-optq.htm#qhull">Qhull</a> -• <a href="qh-optc.htm#prec">Precision</a> +• <a href="qh-optq.htm#qhull">Qhull</a> +• <a href="qh-optc.htm#prec">Precision</a> • <a href="qh-optt.htm#trace">Trace</a><br> -<b>To:</b> <a href="#synopsis">sy</a>nopsis -• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs -• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics -• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions +<b>To:</b> <a href="#synopsis">sy</a>nopsis +• <a href="#input">in</a>put • <a href="#outputs">ou</a>tputs +• <a href="#controls">co</a>ntrols • <a href="#graphics">gr</a>aphics +• <a href="#notes">no</a>tes • <a href="#conventions">co</a>nventions • <a href="#options">op</a>tions <!-- GC common information --> <hr> diff --git a/index.htm b/index.htm index 9cb22f9..8ca94d7 100644 --- a/index.htm +++ b/index.htm @@ -2,7 +2,7 @@ <html> <head> -<title>Qhull for Convex Hull, Delaunay Triangulation, Voronoi Diagram, and Halfspace Intersection about a Point</title> +<title>Qhull code for Convex Hull, Delaunay Triangulation, Voronoi Diagram, and Halfspace Intersection about a Point</title> </head> <body> @@ -11,12 +11,12 @@ <br><b>To:</b> <a href="http://www.qhull.org/news">News</a> • <a href="http://www.qhull.org/download">Download</a> -• <a href="http://citeseer.nj.nec.com/83502.html">CiteSeer</a> +• <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.54.6345">CiteSeer</a> • <a href=http://images.google.com/images?q=qhull&num=100>Images</a> • <a href="html/index.htm#TOC">Manual</a> • <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a> • <a href="html/qh-quick.htm#programs">Programs</a> -• <a href="html/qh-quick.htm#options">Options</a> +• <a href="html/qh-quick.htm#options">Options</a> </p> <hr> @@ -29,11 +29,11 @@ src="html/qh--cone.gif" alt="[CONE]" align="middle" width="100" height="100"></a> </td><td> -Qhull computes convex hulls, Delaunay triangulations, -halfspace intersections about a point, Voronoi diagrams, furthest-site Delaunay -triangulations, and furthest-site Voronoi diagrams. 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 +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> @@ -45,20 +45,30 @@ and higher. </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> about Qhull </li> + <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 2003.1 2003/12/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://savannah.gnu.org/projects/qhull/>Qhull development</a> at Savannah + <li><a href=http://savannah.nongnu.org/projects/qhull/>Development</a> at Savannah + <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#use">How</a> is Qhull used?</li> - <li><a href="http://citeseer.nj.nec.com/context/86585/83502">CiteSeer</a> references to Qhull + <li><a href="http://www.qhull.org/news/qhull-news.html#users">How</a> is Qhull used?</li> + <li><a href="http://citeseer.ist.psu.edu/context/86585/83502">CiteSeer</a> references to Qhull </p> - <li><a href=http://www.google.com/search?as_q=qhull&num=100>Google</a> Qhull, - Qhull <a href=http://images.google.com/images?q=qhull&num=100>Images</a>, + <li> + <a href=http://www.google.com/search?as_q=qhull+-debian+-cvs+-gentoo+-pool+-mirrors&num=100>Google</a> Qhull, + Qhull <a href="http://images.google.com/images?q=qhull&num=100">Images</a>, + Qvoronoi <a href="http://home.scarlet.be/zoetrope/voronoi3d/index.htm">Models</a>, Qhull in <a href=http://groups.google.com/groups?as_q=qhull&num=100&as_scoring=d>Newsgroups</a>, and <a href=http://www.googlism.com/who_is/q/qhull/>Who is</a> Qhull? @@ -69,41 +79,60 @@ and higher. </p> <a href=http://www.mathworks.com/access/helpdesk/help/techdoc/ref/griddatan.shtml>griddatan</a> <a href=http://www.mathworks.com/access/helpdesk/help/techdoc/ref/tsearch.shtml>tsearch</a> <a href=http://www.mathworks.com/access/helpdesk/help/techdoc/ref/tsearchn.shtml>tsearchn</a> - <a href=http://www.mathworks.com/access/helpdesk/help/techdoc/ref/voronoin.shtml>voronoin</a>. MATLAB R14 will upgrade to - Qhull 2003.1 and triangulated output ('Qt'). + <a href=http://www.mathworks.com/access/helpdesk/help/techdoc/ref/voronoin.shtml>voronoin</a>. MATLAB R14 upgraded + to Qhull 2002.1 and triangulated output ('Qt'). </li> <li><a href=http://www.octave.org/>GNU Octave</a> uses Qhull for their - <a href=http://octave.sourceforge.net/index/analysis.html#Geometry>computational geometry functions</a>. Octave has partially upgraded - to Qhull 2002.1 and triangulated output ('Qt'). - <li><a href=http://www.wolfram.com/products/mathematica/>Mathematica</a>'s Delaunay interface: <a href=http://www.mathsource.com/Content/Enhancements/Geometry/0211-251>qh-math</a> + <a href=http://octave.sourceforge.net/index/analysis.html#Geometry>computational geometry</a> functions. + <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> <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.ifor.math.ethz.ch/staff/fukuda/polyfaq/polyfaq.html">Fukuda's - introduction</a> to convex hulls, Delaunay + 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> + 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> + 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/qh-quick.htm#programs">Programs</a> and <a href="html/qh-quick.htm#options">Options</a> <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 - <li><a href=src/index.htm>Qhull functions</a>, macros, and data structures with source + </ul></td><td><ul> + <li><a href="html/index.htm#description">Description</a> of Qhull + <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="src/index.htm">Qhull functions</a>, macros, and data structures with source </ul> + </td></tr></table> <li><a href="http://www.qhull.org/html/qh-faq.htm">Frequently</a> asked questions about Qhull</li> <li>Send e-mail to <a href=mailto:qhull@qhull.org>qhull@qhull.org</a> </li> @@ -116,25 +145,25 @@ and higher. </p> <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> + <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://netlib.bell-labs.com/netlib/voronoi/hull.html">Clarkson's + 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 + <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</li> - <li><a href="http://www.inf.ethz.ch/personal/gaertner/miniball.html">Gartner's + <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://directory.google.com/Top/Science/Math/Geometry/Computational_Geometry/Software/>Google's directory</a> for + <li><a href=http://directory.google.com/Top/Science/Math/Geometry/Computational_Geometry/Software/>Google's directory</a> for Science > Math > Geometry > Computational Geometry > Software - <li><a href=http://www.algorithmic-solutions.com/enleda.htm>Leda</a> + <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.magic-software.com>Magic Software</a> source code for computer @@ -147,16 +176,17 @@ geometry programs and other combinatorial algorithms 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=ftp://ftp.zib.de/pub/Packages/mathprog/index.html>Skorobohatyj's Mathprog@ZIB</a> for + <li><a href=ftp://ftp.zib.de/pub/Packages/mathprog/index.html>Skorobohatyj's Mathprog@ZIB</a> for mathematical software <li><a href=http://www.voronoi.com>Voronoi Web Site</a> for all things Voronoi + <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 + for computer graphics algorithms (<a href="http://exaflop.org/docs/cgafaq/cga6.html">geometric</a> structures) </li> <li><a @@ -181,18 +211,17 @@ 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.kitware.com/vtk.html>VTK</a>.</p> +is <a href=http://www.vtk.org/>VTK</a>.</p> <p>For an article about Qhull, download from <a -href="http://citeseer.nj.nec.com/83502.html">CiteSeer</a>: +href="http://citeseer.ist.psu.edu/83502.html">CiteSeer</a> or <a + href="http://portal.acm.org/citation.cfm?doid=235815.235821">www.acm.org</a>: </p> <blockquote> <p>Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull algorithm for convex hulls," <i>ACM Trans. on - Mathematical Software</i>, Dec 1996. <a - href="http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/">http://www.acm.org</a>; - </p> + Mathematical Software</i>, 22(4):469-483, Dec 1996, http://www.qhull.org</p> </blockquote> <p>Abstract: </p> @@ -223,15 +252,15 @@ href="http://citeseer.nj.nec.com/83502.html">CiteSeer</a>: <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> +<br><b>To:</b> <a href="http://www.qhull.org/news">News</a> • <a href="http://www.qhull.org/download">Download</a> -• <a href="http://citeseer.nj.nec.com/83502.html">CiteSeer</a> +• <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.54.6345">CiteSeer</a> • <a href=http://images.google.com/images?q=qhull&num=100>Images</a> • <a href="html/index.htm#TOC">Manual</a> • <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a> • <a href="html/qh-quick.htm#programs">Programs</a> -• <a href="html/qh-quick.htm#options">Options</a> +• <a href="html/qh-quick.htm#options">Options</a> <!-- GC common information --></p> <hr> @@ -241,6 +270,6 @@ 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 --> +Created: May 17 1995 --- <!-- hhmts start --> </body> </html> diff --git a/qtpro/qhull-qt/qhull-qt.pro b/qtpro/qhull-qt/qhull-qt.pro new file mode 100644 index 0000000..5330bb4 --- /dev/null +++ b/qtpro/qhull-qt/qhull-qt.pro @@ -0,0 +1,84 @@ +# ------------------------------------------------- +# qhull-qt.pro -- Qt project file +# ------------------------------------------------- +QT -= gui +TARGET = qhull-qt +CONFIG += console \ + qtestlib \ + debug +CONFIG -= app_bundle +TEMPLATE = app +LIBS = ../../libqhull.a +DESTDIR = ../.. +OBJECTS_DIR = ../../tmp/obj +MOC_DIR = ../../tmp/moc +RCC_DIR = ../../tmp/rcc +INCLUDEPATH = ../../cpp;../../cpp/road;../../tmp +VPATH = ../.. +SOURCES += cpp/Coordinates.cpp +SOURCES += cpp/QhullVertexSet.cpp +SOURCES += cpp/QhullHyperplane.cpp +SOURCES += cpp/PointCoordinates.cpp +SOURCES += cpp/Qhull.cpp +SOURCES += cpp/QhullError.cpp +SOURCES += cpp/QhullEvent.cpp +SOURCES += cpp/QhullFacet.cpp +SOURCES += cpp/QhullFacetList.cpp +SOURCES += cpp/QhullFacetSet.cpp +SOURCES += cpp/QhullPoint.cpp +SOURCES += cpp/QhullPoints.cpp +SOURCES += cpp/QhullPointSet.cpp +SOURCES += cpp/QhullQh.cpp +SOURCES += cpp/QhullRidge.cpp +SOURCES += cpp/QhullSet.cpp +SOURCES += cpp/QhullStat.cpp +SOURCES += cpp/QhullVertex.cpp +SOURCES += cpp/RboxPoints.cpp +SOURCES += cpp/UsingQhullLib.cpp +SOURCES += cpp/road/RoadError.cpp +SOURCES += cpp/road/RoadLogEvent.cpp +SOURCES += cpp/road/RoadTest.cpp +SOURCES += cpp/qhulltest/Coordinates_test.cpp +SOURCES += cpp/qhulltest/PointCoordinates_test.cpp +SOURCES += cpp/qhulltest/Qhull_test.cpp +SOURCES += cpp/qhulltest/QhullFacet_test.cpp +SOURCES += cpp/qhulltest/QhullFacetList_test.cpp +SOURCES += cpp/qhulltest/QhullFacetSet_test.cpp +SOURCES += cpp/qhulltest/QhullHyperplane_test.cpp +SOURCES += cpp/qhulltest/QhullLinkedList_test.cpp +SOURCES += cpp/qhulltest/QhullPoint_test.cpp +SOURCES += cpp/qhulltest/QhullPoints_test.cpp +SOURCES += cpp/qhulltest/QhullPointSet_test.cpp +SOURCES += cpp/qhulltest/QhullRidge_test.cpp +SOURCES += cpp/qhulltest/QhullSet_test.cpp +SOURCES += cpp/qhulltest/qhulltest.cpp +SOURCES += cpp/qhulltest/QhullVertex_test.cpp +SOURCES += cpp/qhulltest/UsingQhullLib_test.cpp +SOURCES += cpp/qhulltest/RboxPoints_test.cpp +HEADERS += cpp/Coordinates.h +HEADERS += cpp/QhullHyperplane.h +HEADERS += cpp/functionObjects.h +HEADERS += cpp/PointCoordinates.h +HEADERS += cpp/Qhull.h +HEADERS += cpp/QhullError.h +HEADERS += cpp/QhullEvent.h +HEADERS += cpp/QhullFacet.h +HEADERS += cpp/QhullFacetList.h +HEADERS += cpp/QhullFacetSet.h +HEADERS += cpp/QhullIterator.h +HEADERS += cpp/QhullLinkedList.h +HEADERS += cpp/QhullPoint.h +HEADERS += cpp/QhullPoints.h +HEADERS += cpp/QhullPointSet.h +HEADERS += cpp/QhullQh.h +HEADERS += cpp/QhullRidge.h +HEADERS += cpp/QhullSet.h +HEADERS += cpp/QhullSets.h +HEADERS += cpp/QhullStat.h +HEADERS += cpp/QhullVertex.h +HEADERS += cpp/RboxPoints.h +HEADERS += cpp/UsingQhullLib.h +HEADERS += cpp/road/RoadError.h +HEADERS += cpp/road/RoadLogEvent.h +HEADERS += cpp/road/RoadTest.h +QMAKE_MOC_SRC += cpp/qhulltest/UsingQhullLib_test.cpp diff --git a/qtpro/qhulllib/qhulllib.pro b/qtpro/qhulllib/qhulllib.pro new file mode 100644 index 0000000..76189a8 --- /dev/null +++ b/qtpro/qhulllib/qhulllib.pro @@ -0,0 +1,59 @@ +# ------------------------------------------------- +# qhulllib.pro -- Qt project file +# ------------------------------------------------- +# configure -commercial -no-qt3support -no-opengl -no-rtti -qt-style-plastique +QT -= gui +TARGET = ../../qhull +CONFIG += debug +CONFIG -= app_bundle +TEMPLATE = lib +DESTDIR = ../../tmp/lib +OBJECTS_DIR = ../../tmp/obj +MOC_DIR = ../../tmp/moc +RCC_DIR = ../../tmp/rcc +# INCLUDEPATH = ../src +VPATH= ../.. +SOURCES += src/geom.c +SOURCES += src/geom2.c +SOURCES += src/global.c +SOURCES += src/io.c +SOURCES += src/mem.c +SOURCES += src/merge.c +SOURCES += src/poly2.c +SOURCES += src/poly.c +SOURCES += src/qhulllib.c +SOURCES += src/qset.c +SOURCES += src/random.c +SOURCES += src/rboxlib.c +SOURCES += src/stat.c +SOURCES += src/user.c +SOURCES += src/usermem.c +SOURCES += src/userprintf.c +OTHER_FILES += src/Changes.txt +OTHER_FILES += src/index.htm +OTHER_FILES += src/Make-config.sh +OTHER_FILES += src/Makefile.txt +OTHER_FILES += src/Mborland +OTHER_FILES += src/qh-geom.htm +OTHER_FILES += src/qh-globa.htm +OTHER_FILES += src/qh-io.htm +OTHER_FILES += src/qh-mem.htm +OTHER_FILES += src/qh-merge.htm +OTHER_FILES += src/qh-poly.htm +OTHER_FILES += src/qh-qhull.htm +OTHER_FILES += src/qh-set.htm +OTHER_FILES += src/qh-stat.htm +OTHER_FILES += src/qh-user.htm +HEADERS += src/geom.h +HEADERS += src/io.h +HEADERS += src/mem.h +HEADERS += src/merge.h +HEADERS += src/poly.h + +# qhull.h is for backwards compatibility +HEADERS += src/qhulllib.h +HEADERS += src/qhull_a.h +HEADERS += src/qset.h +HEADERS += src/random.h +HEADERS += src/stat.h +HEADERS += src/user.h diff --git a/src/Changes.txt b/src/Changes.txt index 626008a..1e29433 100644 --- a/src/Changes.txt +++ b/src/Changes.txt @@ -1,16 +1,185 @@ .............This file lists all changes to qhull and rbox..................... +Doc +- qhullcpplib must be before qhull.lib _qh_fprintf already defined in qhull.lib +- 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 +- 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]' + +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 + - Better documentation for qhmem totshort, freesize, etc. + - Clean up qhull-news.html XML + - how to change .h, .c, and .cpp to text/html. OK in Opera + - need a page with all QHnnnn for web lookups + - Update citeseer reference in index.htm#ref + - QhullVertex.dimension() is not quite correct, epensive + - Check globalAngleEpsilon + - Deprecate save_qhull() + +Suggestions + C++ class for access to statistics, accumulate vs. add + Add dialog box to RoadError-- a virtual function? + - 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 + +Qhull cpp questions + - size() as size_t, size_type, or int + - Qhull.feasiblePoint interface + - Qhull and RboxPoints messaging + - change qh_printf() to a virtual function + - Figure out RoadError::global_log. clearQhullMessage currently clearGlobalLog + - Should cout << !point.defined() be blank or 'undefined' + - Interface for UsingQhullLib::globalAngleEpsilon(), globalDistanceEpsilon, etc. + - Interface for UsingQhullLib::globalDimension + - Infinite point as !defined() + - qlist and qlinkedlist define pointer, reference, size_type, difference_type, const_pointer, const_reference for the class but not for iterator and const_iterator + +To do + ** Change to static link library before shipping, or define Qt for static linking. + - ignoreWarnings? How to configure Qhull output. Trace and results should go to stdout/stderr + - Fix Qt for conformant triangulations + - Add Qtest::toString() functions for QhullPoint and others. QByteArray and qstrdup() + - rbox"10000" is 10x slower. See Qhull_test -- debug mode? + - Fix gcc failure + - fix const problems + - Review Warn64 + - Fix doc comments + - review all FIXUP. Add dates? + - Qhull_test + - Clear out QhullQh -- it is just the POD type + void checkIfQhullRan(); + void errorAnotherUser(); + void startQhullAccess(); + void stopQhullAccess(); + - PointCoordinatesIterator + - PointCoordinates_test, RboxPoints + - Cleanup PointCoordinates with conversions, etc + - Redo Coordinates w/o vector<> + - Change #include to specific -> general + - Remove class-static code, check K_GLOBAL_STATIC + +qhull 2009.1 2008/03/20 + - Added user_eg3 as an example of Qhull.cpp + - Renamed html/qh-in.htm to html/qh-code.htm + - Report not enough points if d points, Delaunay, and not Qz + - Multithreaded -- call largest dimension for infinityPoint() and origin() + - Oh... Ztotcheck, btw, I had to add to the statistics enum in the qh_KEEPstatistics=0 case in stat.h; otherwise stat.c gets an undefined symbol error. [R. Gardener] + - qh_restore_qhull() zeroes out qh.old_qhstat and qh.old_tempstack. Ownership moved. + - Removed qh.old_stat -- never used + - Removed qhmem.curlong. qa_memfreeshort computes curlong from cntlong and cntfree + - Rewrote save_qhull/restore_qhull + - Add message code to error messages and warnings (e.g., QH6012) + - Renamed qh.coplanarset to coplanarfacetset. Avoids conflict with facetT.coplanarset + - Fixed double-free of facet->centrum for triangulated facets + - Removed qh_clearcenters from qh_freeqhull. Duplicated by qh_delfacet + - Added full tracing for short memory allocations. + - Memory tracing (T5) redone for sort order by object + - Fixed qhmem.totshort (total short memory in use) + - Fixed parentheses around warning for missing 'Qc' [qh_initqhull_outputflags] + - 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 + - Added dim to vertexT for cpp interface. Reduced size of qh.vertex_visit + - Clear qh.ERREXITcalled at end of qh_errexit(). + - Documented Qhull's C++ interface [http://../html/qh-code.htm#cpp] + - Renamed qh-in.htm to qh-code.htm + - Removed qhull_interface.cpp + - Documented <A href="qh-code.htm#cpp">C++ interface</a> + - qh_printfacet [io.c] Removed extra space for neighboring facets + - Allow 'd' and 'v' as the filename for 'TO ..' and 'TI ...' in qdelaunay [M. Jambon] + - Allow quoted filenames for 'TO ...' and 'TI ...' + - qh_printcenter [io.c] removed unreachable fprintf argument + - qh_product_output [io.c] may be called multiple times (C++ interface) + - qh_getarea() [geom2.c] checks facet->isarea. Set by QhullFacet.facetArea() + - qh_getarea() [geom2.c] ignored on multiple calls (qh.hasAreaVolume) + - qh_triangulate() [poly2.c] ignored on multiple calls (qh.hasTriangulation) + - Moved SETsizeaddr_() to qset.h for use by QhullSet.cpp + - Add statistics for vertex_visit and visit_id to buildtracing + - Add reference to 'Qt' to 'i' + - Add reference to 'FS' to 'FA' + - qh-impre.htm discusses precision issues for halfspace intersection + - Defined qh_OPTIONline [user.h] as max length of option line ('FO') + - Option 'Tz' sets flag qh.USEstdout for QhullPoints.cpp + - Add cross references between options 'FA' and 'FS' + - Report all hidden options before exiting in qh_checkflags() + - Added option 'Ta' to annotate output with message codes + - 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 + - Updated copyright to 2008 + - Moved qh_strtod/qh_strtol from global.c to random.c for use in rboxlib.c + - 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 rbox ignoring flags that were not separated by spaces + - Fixed rbox buffer overflow of 'command' when appending seedbuf + - Fixed upper bound of sanity check for qh_RANDOMmax in qh_initqhull_globals() + - Report error if negative arguments to rbox 'G', 'L', 'Z' + - Unknown rbox flag changed from a warning to an error + - Split out random functions into random.c + - Defined scale and offset parameters for qh_randomfactor + - Set error status 4 qh_ERRmem if rbox runs out of memory + - In qh_printafacet(), changed error output to 'qh ferr' + - Added message codes to qh_fprintf(). See its definition in user.c + - In mem.h, changed ptr_intT to long. qh_meminit() checks that it holds a 'void*' + - Fixed 64-bit warnings (marked with "WARN64") + - qhull.exe is ... faster/slower + - Add sln and vcproj files for building Qhull -- add to README notes + - Removed extra spaces at end of line + - Fixed warnings at VC8, level 4 + - In qhulllib.c, added explicit casts from long to float, Avoids warning + - In global.c, cast time() to int for QRandom-seed. Avoids warning + - 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 + - Fixed mindist initialization if !testcentrum in io.c findbest_test [Ratcliff] + - Added link to Wolfram Research's MathWorld site + - Updated Fukuda's links + - Updated Qhull citation with page numbers. + - Proposed project: constructing Voronoi diagram + - Proposed project: computing Voronoi volumes + - Fixed qh_findfacet_all(), "REALmin" should be "-REALmax" [L.A. Taylor]. + Effects library users for convex hulls and halfspace intersections. + 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] + 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 @@ -22,9 +191,9 @@ 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 + 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] @@ -58,7 +227,7 @@ Changes to examples qhull 2002.1 2002/8/20 Changes to distribution: - - Set up savannah.gnu.org/projects/qhull/ [R. Laboissiere] + - 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] @@ -69,7 +238,7 @@ Bug fixes: - Fixed sign of coefficients for cdd halfspaces ('FD','Fd') [T. Abraham] Changes to code: - - Replace qh_version with qh_VERSION in qhull.h. + - Replace qh_version with qh_VERSION in qhulllib.h. Allows shared libraries and single point of definition - Added qh.TESTpoints for future implementation of tsearch @@ -122,7 +291,7 @@ Corrections to code 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 + 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 @@ -151,14 +320,14 @@ Changes to documentation - 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. + 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 qhull.h for qhull options + - src/index.htm: Added how to search qhulllib.h for qhull options - qvoronoi.htm/qdelaun.htm: 'Fc' and 'FN' includes deleted vertices Changes to URLs @@ -298,7 +467,7 @@ qhull 2.6 1998/12/30 - 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-in.htm to compute largest empty circle [Hase] + - 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] @@ -372,7 +541,7 @@ qhull 2.5 1998/1/28 - add unpacking instructions to README.txt - updated discussion of forced output, 'Po' - sorted the options alphabetically - - removed __STDC__ check from qhull.h for VisualC++ + - removed __STDC__ check from qhulllib.h for VisualC++ - moved qh_markvoronoi from qh_printvoronoi and cleared facet->seen flags - added facet->seen2 flag for 'Fv' @@ -413,7 +582,7 @@ Changes to documentation - 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-in.htm [A. Tsui] + - 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 @@ -434,7 +603,7 @@ Changes for the Qhull library - 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 qhull.h [C. Begnis] + - expanded __STDC__ warning message in qhulllib.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 @@ -486,7 +655,7 @@ Corrections 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-in.htm for Qhull internals + - 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 @@ -536,7 +705,7 @@ qhull V2.3 96/6/5 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. + 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'. @@ -748,7 +917,7 @@ qhull V2.1 95/9/25 other documentation changes: - new URLs for graphics images - - fixed comment for facetT.neighbors in qhull.h [P. Soikkonen] + - fixed comment for facetT.neighbors in qhulllib.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] @@ -797,7 +966,7 @@ qhull V2.1 6/3/95 qhull V2.1 beta 5/15/95 - ======= main changes ======== + ======= 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 @@ -842,14 +1011,14 @@ qhull V2.1 beta 5/15/95 - 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 ======= + ======= 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, 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() @@ -861,7 +1030,7 @@ qhull V2.1 beta 5/15/95 - 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 ============ + ======== 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 @@ -871,8 +1040,8 @@ qhull V2.1 beta 5/15/95 - forcing output on error ('Po') fixed for options 'n' 'o' 'i' 's' - fixed optimization error on HP machines [fprintf(... *p++)] - ======== changes to qhull.h for user code ======= - - qh_collectstatistics and qh_printstatistics removed from qhull.h. + ======== changes to qhulllib.h for user code ======= + - qh_collectstatistics and qh_printstatistics removed from qhulllib.h. should use qh_printallstatistics instead - qh_findbest uses boolT for newfacets - added qh_findbestnew for non-simplicial facets. qh_findbest is @@ -884,7 +1053,7 @@ qhull V2.1 beta 5/15/95 - added dfacet/dvertex for printing facets/vertices while debugging - added qh_produce_output and qh_printsummary - ======== changes to code ========== + ======== 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 @@ -896,7 +1065,7 @@ qhull V2.1 beta 5/15/95 - 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 ======= + ========== 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 @@ -962,12 +1131,12 @@ qhull V2.01 6/11/94 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 + 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 @@ -986,18 +1155,18 @@ 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" + 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 + 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 + 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" @@ -1008,15 +1177,15 @@ qhull V2.01 6/2/94 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 + 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 qhull.h for doubles + - qhull and rbox now use floats, change REALfloat in qhulllib.h for doubles - qhull 2.00 fixes several initialization errors and performanace errors - e.g., "singular input" on data with lots of 0 coordinates + 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' diff --git a/src/Make-config.sh b/src/Make-config.sh index cc24786..b567bae 100644 --- a/src/Make-config.sh +++ b/src/Make-config.sh @@ -25,7 +25,7 @@ dnl configure.in for the qhull package dnl Author: Rafael Laboissiere <rafael@debian.org> dnl Created: Mon Dec 3 21:36:21 CET 2001 -AC_INIT(src/qhull.c) +AC_INIT(src/qhulllib.c) AM_INIT_AUTOMAKE(qhull, 2002.1) AC_PROG_CC @@ -140,7 +140,7 @@ html_DATA = \ qh-faq.htm \ qh-get.htm \ qh-impre.htm \ - qh-in.htm \ + qh-code.htm \ qh-optc.htm \ qh-optf.htm \ qh-optg.htm \ @@ -181,23 +181,24 @@ cat >../src/Makefile.am <<\HERE-SRC # to: lib_LTLIBRARIES = libqhull.la -# from: +# from (frequently used files at end): libqhull_la_SOURCES = \ user.c \ global.c \ + random.c \ stat.c \ io.c \ geom2.c \ poly2.c \ merge.c \ - qhull.c \ + qhulllib.c \ geom.c \ poly.c \ qset.c \ mem.c # how: -libqhull_la_LDFLAGS = -version-info 0:0:0 -lm +libqhull_la_LDFLAGS = -version-info 4:0:0 -lm ### Utility programs @@ -230,7 +231,7 @@ pkginclude_HEADERS = \ stat.h \ io.h \ merge.h \ - qhull.h \ + qhulllib.h \ qset.h \ user.h @@ -279,7 +280,7 @@ HERE-SRC echo Run automake, libtoolize, and autoconf cd ..; aclocal &&\ + libtoolize --force --copy && \ automake --foreign --add-missing --force-missing && \ - libtoolize --force && \ autoconf diff --git a/src/Makefile b/src/Makefile.txt similarity index 88% rename from src/Makefile rename to src/Makefile.txt index 5d5f8d8..5e9d4f4 100644 --- a/src/Makefile +++ b/src/Makefile.txt @@ -61,17 +61,17 @@ CCOPTS1 = -O2 -ansi # for loader, ld CCOPTS2 = $(CCOPTS1) -# OBJS in execution frequency order. CFILES after qhull.c are alphabetical -OBJS = user.o global.o stat.o io.o geom2.o poly2.o \ +# OBJS in execution frequency order. CFILES after qhulllib.c are alphabetical +OBJS = user.o global.o random.o stat.o io.o geom2.o poly2.o \ merge.o qhull.o geom.o poly.o qset.o mem.o -CFILES= unix.c qhull.c geom.c geom2.c global.c io.c mem.c merge.c poly.c \ - poly2.c qset.c stat.c user.c qconvex.c qdelaun.c qhalf.c qvoronoi.c -HFILES= user.h qhull.h qhull_a.h geom.h io.h mem.h merge.h poly.h qset.h stat.h +CFILES= unix.c qhulllib.c geom.c geom2.c global.c io.c mem.c merge.c poly.c \ + poly2.c random.c qset.c stat.c user.c qconvex.c qdelaun.c qhalf.c qvoronoi.c +HFILES= user.h qhulllib.h qhull_a.h geom.h io.h mem.h merge.h poly.h random.h qset.h stat.h TXTFILES= ../Announce.txt ../REGISTER.txt ../COPYING.txt ../README.txt Changes.txt DOCFILES= ../html/rbox.txt ../html/qhull.txt FILES= Makefile rbox.c user_eg.c ../eg/q_test ../eg/q_egtest ../eg/q_eg -HTMFILES= qhull.man rbox.man qh-in.htm qh-optg.htm qh-optt.htm qh-optp.htm \ +HTMFILES= qhull.man rbox.man qh-code.htm qh-optg.htm qh-optt.htm qh-optp.htm \ index.htm qh-quick.htm qh-impre.htm qh-eg.htm \ qh-optc.htm qh-opto.htm qh-optf.htm qh-optq.htm \ qh-c.htm qh-faq.htm qhull.htm qconvex.htm qdelaun.htm \ @@ -81,11 +81,11 @@ HTMFILES= qhull.man rbox.man qh-in.htm qh-optg.htm qh-optt.htm qh-optp.htm \ all: rbox qconvex qdelaunay qhalf qvoronoi qhull -unix.o: qhull.h user.h mem.h -qconvex.o: qhull.h user.h mem.h -qdelaun.o: qhull.h user.h mem.h -qhalf.o: qhull.h user.h mem.h -qvoronoi.o: qhull.h user.h mem.h +unix.o: qhulllib.h user.h mem.h +qconvex.o: qhulllib.h user.h mem.h +qdelaun.o: qhulllib.h user.h mem.h +qhalf.o: qhulllib.h user.h mem.h +qvoronoi.o: qhulllib.h user.h mem.h qhull.o: $(HFILES) geom.o: $(HFILES) geom2.o: $(HFILES) @@ -95,6 +95,7 @@ mem.o: mem.h merge.o: $(HFILES) poly.o: $(HFILES) poly2.o: $(HFILES) +random.o: qhulllib.h random.h qset.o: qset.h mem.h stat.o: $(HFILES) user.o: $(HFILES) diff --git a/src/Mborland b/src/Mborland index 3a1d93a..94c9705 100644 --- a/src/Mborland +++ b/src/Mborland @@ -42,10 +42,10 @@ EXEEG2 = user_eg2 TMPFILE = BCC32tmp.cfg -OBJS1 = global.obj stat.obj geom2.obj poly2.obj io.obj +OBJS1 = global.obj random.obj stat.obj geom2.obj poly2.obj io.obj OBJS2 = merge.obj qhull.obj mem.obj qset.obj poly.obj geom.obj -HFILES1 = qhull.h stat.h qhull_a.h user.h +HFILES1 = qhulllib.h stat.h qhull_a.h user.h # General rules @@ -172,15 +172,16 @@ new: cleanall all # Header file dependencies qhull.obj stat.obj user.obj global.obj: $(HFILES1) +random.obj: qhulllib.h random.h geom.obj geom2.obj: $(HFILES1) geom.h poly.obj poly2.obj: $(HFILES1) poly.h io.obj: $(HFILES1) io.h merge.obj: $(HFILES1) merge.h mem.obj: mem.h qset.obj: qset.h mem.h -unix.obj: qhull.h user.h -qconvex.obj: qhull.h user.h -qdelaun.obj: qhull.h user.h -qhalf.obj: qhull.h user.h -qvoronoi.obj: qhull.h user.h +unix.obj: qhulllib.h user.h +qconvex.obj: qhulllib.h user.h +qdelaun.obj: qhulllib.h user.h +qhalf.obj: qhulllib.h user.h +qvoronoi.obj: qhulllib.h user.h rbox.obj: user.h diff --git a/src/geom.c b/src/geom.c index af633ee..ceb534f 100644 --- a/src/geom.c +++ b/src/geom.c @@ -1,40 +1,43 @@ /*<html><pre> -<a href="qh-geom.htm" >-------------------------------</a><a name="TOP">-</a> - geom.c + geom.c geometric routines of qhull see qh-geom.htm and geom.h - copyright (c) 1993-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/geom.c#25 $$Change: 1047 $ + $DateTime: 2009/09/12 21:08:23 $$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: + + notes: dist > 0 if point is above facet (i.e., outside) - does not error (for sortfacets) - + 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) { +void qh_distplane(pointT *point, facetT *facet, realT *dist) { coordT *normal= facet->normal, *coordp, randr; int k; - - switch(qh hull_dim){ + + switch (qh hull_dim){ case 2: *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1]; break; @@ -50,7 +53,7 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { 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: + 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: @@ -59,7 +62,7 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { default: *dist= facet->offset; coordp= point; - for (k= qh hull_dim; k--; ) + for (k=qh hull_dim; k--; ) *dist += *coordp++ * *normal++; break; } @@ -72,9 +75,9 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { qh RANDOMfactor * qh MAXabs_coord; } if (qh IStracing >= 4) { - fprintf (qh ferr, "qh_distplane: "); - fprintf (qh ferr, qh_REAL_1, *dist); - fprintf (qh ferr, "from p%d to f%d\n", qh_pointid(point), facet->id); + 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 */ @@ -82,15 +85,15 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { /*-<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 + 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 + if !bestoutside(qh_ALL), stops at qh.MINoutside returns: best facet (reports error if NULL) @@ -101,7 +104,7 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { 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 @@ -116,11 +119,11 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { 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(), + 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 + this is best facet overall if dist > - qh.MAXcoplanar or hull has at least a "spherical" curvature design: @@ -134,7 +137,7 @@ void qh_distplane (pointT *point, facetT *facet, realT *dist) { if so, future calls go to qh_findbestnew() test horizon facets */ -facetT *qh_findbest (pointT *point, facetT *startfacet, +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 */; @@ -146,21 +149,21 @@ facetT *qh_findbest (pointT *point, facetT *startfacet, 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 IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid(point))) { if (qh TRACElevel > qh IStracing) qh IStracing= qh TRACElevel; - fprintf (qh ferr, "qh_findbest: point p%d starting at f%d isnewfacets? %d, unless %d exit if > %2.2g\n", + qh_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); - fprintf(qh ferr, " testhorizon? %d noupper? %d", testhorizon, noupper); - fprintf (qh ferr, " Last point added was p%d.", qh furthest_id); - fprintf(qh ferr, " Last merge was #%d. max_outside %2.2g\n", zzval_(Ztotmerge), qh max_outside); + 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 + qh_distplane(point, startfacet, dist); /* this code is duplicated below */ + if (!bestoutside && *dist >= qh MINoutside && (!startfacet->upperdelaunay || !noupper)) { bestfacet= startfacet; goto LABELreturn_best; @@ -168,13 +171,13 @@ facetT *qh_findbest (pointT *point, facetT *startfacet, bestdist= *dist; if (!startfacet->upperdelaunay) { bestfacet= startfacet; - } - }else + } + }else *numpart= 0; startfacet->visitid= visitid; facet= startfacet; while (facet) { - trace4((qh ferr, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n", + 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) { @@ -185,9 +188,9 @@ facetT *qh_findbest (pointT *point, facetT *startfacet, neighbor->visitid= visitid; if (!neighbor->flipped) { /* code duplicated above */ (*numpart)++; - qh_distplane (point, neighbor, dist); + qh_distplane(point, neighbor, dist); if (*dist > bestdist) { - if (!bestoutside && *dist >= qh MINoutside + if (!bestoutside && *dist >= qh MINoutside && (!neighbor->upperdelaunay || !noupper)) { bestfacet= neighbor; goto LABELreturn_best; @@ -196,7 +199,7 @@ facetT *qh_findbest (pointT *point, facetT *startfacet, bestfacet= neighbor; bestdist= *dist; break; /* switch to neighbor */ - }else if (!bestfacet) { + }else if (!bestfacet) { bestdist= *dist; break; /* switch to neighbor */ } @@ -205,26 +208,26 @@ facetT *qh_findbest (pointT *point, facetT *startfacet, } /* end of FOREACHneighbor */ facet= neighbor; /* non-NULL only if *dist>bestdist */ } /* end of while facet (directed search) */ - if (isnewfacets) { + if (isnewfacets) { if (!bestfacet) { - bestdist= -REALmax/2; - bestfacet= qh_findbestnew (point, startfacet->next, &bestdist, bestoutside, isoutside, &numpartnew); + 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()) { + if (qh_sharpnewfacets()) { /* seldom used, qh_findbestnew will retest all facets */ zinc_(Zfindnewsharp); - bestfacet= qh_findbestnew (point, bestfacet, &bestdist, bestoutside, isoutside, &numpartnew); + 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); + 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; @@ -239,14 +242,14 @@ LABELreturn_best: /*-<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): + returns(ischeckmax): best facet - returns (!ischeckmax): + returns(!ischeckmax): best facet that is not upperdelaunay allows upperdelaunay that is clearly outside returns: @@ -266,7 +269,7 @@ LABELreturn_best: 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 + 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: @@ -275,12 +278,12 @@ LABELreturn_best: unless upperdelaunay or clearly outside update best facet */ -facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart) { +facetT *qh_findbesthorizon(boolT ischeckmax, pointT* point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart) { facetT *bestfacet= startfacet; realT dist; facetT *neighbor, **neighborp, *facet; - facetT *nextfacet= NULL; /* optimize last facet of coplanarset */ - int numpartinit= *numpart, coplanarset_size; + 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 */ @@ -299,18 +302,18 @@ facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, /* Always check coplanar facets. Needed for RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv */ minimize_(minsearch, -searchdist); } - coplanarset_size= 0; + coplanarfacetset_size= 0; facet= startfacet; while (True) { - trace4((qh ferr, "qh_findbesthorizon: neighbors of f%d bestdist %2.2g f%d ischeckmax? %d noupper? %d minsearch %2.2g searchdist %2.2g\n", + 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) + if (neighbor->visitid == visitid) continue; neighbor->visitid= visitid; - if (!neighbor->flipped) { - qh_distplane (point, neighbor, &dist); + if (!neighbor->flipped) { + qh_distplane(point, neighbor, &dist); (*numpart)++; if (dist > *bestdist) { if (!neighbor->upperdelaunay || ischeckmax || (!noupper && dist >= qh MINoutside)) { @@ -320,52 +323,52 @@ facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, if (!ischeckmax) { minsearch= dist - searchdist; if (dist > *bestdist + searchdist) { - zinc_(Zfindjump); /* everything in qh.coplanarset at least searchdist below */ - coplanarset_size= 0; + zinc_(Zfindjump); /* everything in qh.coplanarfacetset at least searchdist below */ + coplanarfacetset_size= 0; } } } - }else if (dist < minsearch) + }else if (dist < minsearch) continue; /* if ischeckmax, dist can't be positive */ #if qh_MAXoutside if (ischeckmax && dist > neighbor->maxoutside) neighbor->maxoutside= dist; -#endif +#endif } /* end of !flipped */ if (nextfacet) { - if (!coplanarset_size++) { - SETfirst_(qh coplanarset)= nextfacet; - SETtruncate_(qh coplanarset, 1); + if (!coplanarfacetset_size++) { + SETfirst_(qh coplanarfacetset)= nextfacet; + SETtruncate_(qh coplanarfacetset, 1); }else - qh_setappend (&qh coplanarset, nextfacet); /* Was needed for RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv + 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) + if (facet) nextfacet= NULL; - else if (!coplanarset_size) - break; - else if (!--coplanarset_size) { - facet= SETfirst_(qh coplanarset); - SETtruncate_(qh coplanarset, 0); + else if (!coplanarfacetset_size) + break; + else if (!--coplanarfacetset_size) { + facet= SETfirstt_(qh coplanarfacetset, facetT); + SETtruncate_(qh coplanarfacetset, 0); }else - facet= (facetT*)qh_setdellast (qh coplanarset); - } /* while True, for each facet in qh.coplanarset */ + 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, "qh_findbesthorizon: newbest? %d bestfacet f%d bestdist %2.2g\n", newbest, getid_(bestfacet), *bestdist)); + 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 @@ -382,8 +385,8 @@ facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, Always used for merged new facets (see qh_USEfindbestnew) Avoids upperdelaunay facet unless (isoutside and outside) - Uses qh.visit_id, qh.coplanarset. - If share visit_id with qh_findbest, coplanarset is incorrect. + 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, @@ -406,7 +409,7 @@ facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, update best facet test horizon facets */ -facetT *qh_findbestnew (pointT *point, facetT *startfacet, +facetT *qh_findbestnew(pointT *point, facetT *startfacet, realT *dist, boolT bestoutside, boolT *isoutside, int *numpart) { realT bestdist= -REALmax/2; facetT *bestfacet= NULL, *facet; @@ -418,11 +421,11 @@ facetT *qh_findbestnew (pointT *point, facetT *startfacet, if (!startfacet) { if (qh MERGING) - fprintf(qh ferr, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets. Can not continue.\n"); + 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 - fprintf(qh ferr, "qhull internal error (qh_findbestnew): no new facets for point p%d\n", - qh furthest_id); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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) @@ -434,22 +437,22 @@ facetT *qh_findbestnew (pointT *point, facetT *startfacet, if (isoutside) *isoutside= True; *numpart= 0; - if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid (point))) { + if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid(point))) { if (qh TRACElevel > qh IStracing) qh IStracing= qh TRACElevel; - fprintf(qh ferr, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n", + qh_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); - fprintf(qh ferr, " Last point added p%d visitid %d.", qh furthest_id, visitid); - fprintf(qh ferr, " Last merge was #%d.\n", zzval_(Ztotmerge)); + 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) { + 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); + qh_distplane(point, facet, dist); (*numpart)++; if (*dist > bestdist) { if (!facet->upperdelaunay || *dist >= qh MINoutside) { @@ -463,15 +466,15 @@ facetT *qh_findbestnew (pointT *point, facetT *startfacet, } /* FORALLfacet from startfacet or qh newfacet_list */ } if (testhorizon || !bestfacet) - bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, bestfacet ? bestfacet : startfacet, - !qh_NOupper, &bestdist, numpart); + bestfacet= qh_findbesthorizon(!qh_IScheckmax, point, bestfacet ? bestfacet : startfacet, + !qh_NOupper, &bestdist, numpart); *dist= bestdist; if (isoutside && *dist < qh MINoutside) *isoutside= False; LABELreturn_bestnew: zadd_(Zfindnewtot, *numpart); zmax_(Zfindnewmax, *numpart); - trace4((qh ferr, "qh_findbestnew: bestfacet f%d bestdist %2.2g\n", getid_(bestfacet), *dist)); + trace4((qh ferr, 4004, "qh_findbestnew: bestfacet f%d bestdist %2.2g\n", getid_(bestfacet), *dist)); qh IStracing= oldtrace; return bestfacet; } /* findbestnew */ @@ -480,15 +483,15 @@ LABELreturn_bestnew: /*-<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 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 @@ -506,7 +509,7 @@ LABELreturn_bestnew: 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 @@ -515,28 +518,28 @@ LABELreturn_bestnew: if zero divide and not last row set tail of normal to 0 */ -void qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, +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--; ) { + for (i=numrow; i--; ) { *normalp= 0.0; ai= rows[i] + i + 1; ak= normalp+1; - for(j= i+1; j < numcol; j++) + 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); + *normalp= qh_divzero(*normalp, diagonal, qh MINdenom_1_2, &waszero); if (waszero) { zerocol= i; *(normalp--)= (sign ? -1.0 : 1.0); @@ -549,14 +552,14 @@ void qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, if (zerocol != -1) { zzinc_(Zback0); *nearzero= True; - trace4((qh ferr, "qh_backnormal: zero diagonal at column %d.\n", i)); - qh_precision ("zero diagonal on back substitution"); + 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 @@ -579,21 +582,21 @@ void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *near 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++) { + for (k=0; k < numrow; k++) { pivot_abs= fabs_((rows[k])[k]); pivoti= k; - for(i= k+1; i < numrow; i++) { + 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; + rowp= rows[pivoti]; + rows[pivoti]= rows[k]; + rows[k]= rowp; *sign ^= 1; flip ^= 1; } @@ -601,21 +604,21 @@ void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *near *nearzero= True; if (pivot_abs == 0.0) { /* remainder of column == 0 */ if (qh IStracing >= 4) { - fprintf (qh ferr, "qh_gausselim: 0 pivot at column %d. (%2.2g < %2.2g)\n", k, pivot_abs, qh DISTround); - qh_printmatrix (qh ferr, "Matrix:", rows, numrow, numcol); + 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"); + 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++) { + 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--; ) + for (j= numcol - (k+1); j--; ) *ai++ -= n * *ak++; } LABELnextcol: @@ -623,13 +626,13 @@ void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *near } wmin_(Wmindenom, pivot_abs); /* last pivot element */ if (qh IStracing >= 5) - qh_printmatrix (qh ferr, "qh_gausselem: result", rows, numrow, numcol); + 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 @@ -642,21 +645,21 @@ realT qh_getangle(pointT *vect1, pointT *vect2) { realT angle= 0, randr; int k; - for(k= qh hull_dim; k--; ) + for (k=qh hull_dim; k--; ) angle += *vect1++ * *vect2++; if (qh RANDOMdist) { randr= qh_RANDOMint; angle += (2.0 * randr / qh_RANDOMmax - 1.0) * qh RANDOMfactor; } - trace4((qh ferr, "qh_getangle: %2.2g\n", angle)); + 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 @@ -670,8 +673,8 @@ pointT *qh_getcenter(setT *vertices) { int count= qh_setsize(vertices); if (count < 2) { - fprintf (qh ferr, "qhull internal error (qh_getcenter): not defined for %d points\n", count); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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++) { @@ -687,7 +690,7 @@ pointT *qh_getcenter(setT *vertices) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="getcentrum">-</a> - + qh_getcentrum( facet ) returns the centrum for a facet as a new point @@ -700,10 +703,10 @@ pointT *qh_getcentrum(facetT *facet) { point= qh_getcenter(facet->vertices); zzinc_(Zcentrumtests); - qh_distplane (point, facet, &dist); + qh_distplane(point, facet, &dist); centrum= qh_projectpoint(point, facet, dist); qh_memfree(point, qh normal_size); - trace4((qh ferr, "qh_getcentrum: for f%d, %d vertices dist= %2.2g\n", + 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 */ @@ -711,7 +714,7 @@ pointT *qh_getcentrum(facetT *facet) { /*-<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 @@ -725,7 +728,7 @@ pointT *qh_getcentrum(facetT *facet) { 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) @@ -758,17 +761,17 @@ realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *max 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) { +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 @@ -776,16 +779,16 @@ void qh_normalize (coordT *normal, int dim, boolT toporient) { returns: normalized vector flips sign if !toporient - if minnorm non-NULL, + 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 ()) + if divide by zero (divzero()) sets largest element to +/-1 bumps Znearlysingular - + design: computes norm test for minnorm @@ -798,7 +801,7 @@ void qh_normalize (coordT *normal, int dim, boolT toporient) { if nearzero sets norm to direction of maximum value */ -void qh_normalize2 (coordT *normal, int dim, boolT toporient, +void qh_normalize2 (coordT *normal, int dim, boolT toporient, realT *minnorm, boolT *ismin) { int k; realT *colp, *maxp, norm= 0, temp, *norm1, *norm2, *norm3; @@ -812,17 +815,17 @@ void qh_normalize2 (coordT *normal, int dim, boolT toporient, else if (dim == 3) norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2)); else if (dim == 4) { - norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) + norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) + (*norm3)*(*norm3)); }else if (dim > 4) { - norm= (*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) + norm= (*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) + (*norm3)*(*norm3); - for (k= dim-4, colp= normal+4; k--; colp++) + for (k=dim-4, colp=normal+4; k--; colp++) norm += (*colp) * (*colp); norm= sqrt(norm); } if (minnorm) { - if (norm < *minnorm) + if (norm < *minnorm) *ismin= True; else *ismin= False; @@ -843,28 +846,28 @@ void qh_normalize2 (coordT *normal, int dim, boolT toporient, }else if (dim >4) { *norm2 /= norm; *norm3 /= norm; - for (k= dim-4, colp= normal+4; k--; ) + 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--; ) + 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); + 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++) + for (k=dim, colp=normal; k--; colp++) *colp= 0.0; *maxp= temp; zzinc_(Znearlysingular); - trace0((qh ferr, "qh_normalize: norm=%2.2g too small during p%d\n", + trace0((qh ferr, 1, "qh_normalize: norm=%2.2g too small during p%d\n", norm, qh furthest_id)); return; } @@ -875,13 +878,13 @@ void qh_normalize2 (coordT *normal, int dim, boolT toporient, /*-<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 @@ -891,19 +894,19 @@ pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist) { pointT *newpoint, *np, *normal; int normsize= qh normal_size,k; void **freelistp; /* used !qh_NOmem */ - + qh_memalloc_(normsize, freelistp, newpoint, pointT); np= newpoint; normal= facet->normal; - for(k= qh hull_dim; k--; ) + 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 @@ -938,12 +941,12 @@ void qh_setfacetplane(facetT *facet) { if (facet == qh tracefacet) { oldtrace= qh IStracing; qh IStracing= 5; - fprintf (qh ferr, "qh_setfacetplane: facet f%d created.\n", facet->id); - fprintf (qh ferr, " Last point added to hull was p%d.", qh furthest_id); + 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)) - fprintf(qh ferr, " Last merge was #%d.", zzval_(Ztotmerge)); - fprintf (qh ferr, "\n\nCurrent summary is:\n"); - qh_printsummary (qh ferr); + 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; @@ -952,9 +955,9 @@ void qh_setfacetplane(facetT *facet) { FOREACHvertex_(facet->vertices) { qh gm_row[i++]= gmcoord; coord= vertex->point; - for (k= qh hull_dim; k--; ) - *(gmcoord++)= *coord++ * qh_randomfactor(); - } + for (k=qh hull_dim; k--; ) + *(gmcoord++)= *coord++ * qh_randomfactor(qh RANDOMa, qh RANDOMb); + } }else { FOREACHvertex_(facet->vertices) qh gm_row[i++]= vertex->point; @@ -970,23 +973,23 @@ void qh_setfacetplane(facetT *facet) { qh gm_row[i++]= gmcoord; coord= vertex->point; point= point0; - for(k= qh hull_dim; k--; ) + 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(); + 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, "qh_setfacetplane: flipped orientation after testing interior_point during p%d\n", qh furthest_id)); + 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 @@ -1025,26 +1028,26 @@ void qh_setfacetplane(facetT *facet) { wwval_(Wnewvertexmax)= dist; if (dist > qh max_outside) { qh max_outside= dist; /* used by qh_maxouter() */ - if (dist > qh TRACEdist) + if (dist > qh TRACEdist) istrace= True; } }else if (-dist > qh TRACEdist) istrace= True; if (istrace) { - fprintf (qh ferr, "qh_setfacetplane: ====== vertex p%d (v%d) increases max_outside to %2.2g for new facet f%d last p%d\n", + qh_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_errprint("DISTANT", facet, NULL, NULL, NULL); } } } qh RANDOMdist= qh old_randomdist; } if (qh IStracing >= 3) { - fprintf (qh ferr, "qh_setfacetplane: f%d offset %2.2g normal: ", + 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++) - fprintf (qh ferr, "%2.2g ", facet->normal[k]); - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 8018, "%2.2g ", facet->normal[k]); + qh_fprintf(qh ferr, 8019, "\n"); } if (facet == qh tracefacet) qh IStracing= oldtrace; @@ -1053,10 +1056,10 @@ void qh_setfacetplane(facetT *facet) { /*-<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), + 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 @@ -1095,7 +1098,7 @@ void qh_setfacetplane(facetT *facet) { 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, +void qh_sethyperplane_det(int dim, coordT **rows, coordT *point0, boolT toporient, coordT *normal, realT *offset, boolT *nearzero) { realT maxround, dist; int i; @@ -1161,7 +1164,7 @@ void qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, } if (*nearzero) { zzinc_(Zminnorm); - trace0((qh ferr, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh furthest_id)); + trace0((qh ferr, 3, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh furthest_id)); zzinc_(Znearlysingular); } } /* sethyperplane_det */ @@ -1169,9 +1172,9 @@ void qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, /*-<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) + given(dim-1) X dim array of rows[i]= V_{i+1} - V_0 (point0) set normalized hyperplane equation from oriented simplex returns: @@ -1181,38 +1184,38 @@ void qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 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] + 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 + perform back substitution normalize result compute offset */ -void qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, +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--; ) { + for (k=dim-1; k--; ) { if ((rows[k])[k] < 0) sign ^= 1; } if (*nearzero) { zzinc_(Znearlysingular); - trace0((qh ferr, "qh_sethyperplane_gauss: nearly singular or axis parallel hyperplane during p%d.\n", qh furthest_id)); + 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, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh furthest_id)); + trace0((qh ferr, 5, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh furthest_id)); } } if (nearzero2) @@ -1221,9 +1224,9 @@ void qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, pointcoord= point0; normalcoef= normal; *offset= -(*pointcoord++ * *normalcoef++); - for(k= dim-1; k--; ) + for (k=dim-1; k--; ) *offset -= *pointcoord++ * *normalcoef++; } /* sethyperplane_gauss */ - + diff --git a/src/geom.h b/src/geom.h index 6b8ee62..a402843 100644 --- a/src/geom.h +++ b/src/geom.h @@ -6,12 +6,16 @@ see qh-geom.htm and geom.c - copyright (c) 1993-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/geom.h#14 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ #ifndef qhDEFgeom #define qhDEFgeom 1 +#include "qhulllib.h" + /* ============ -macros- ======================== */ /*-<a href="qh-geom.htm#TOC" @@ -44,7 +48,7 @@ maximize_(maxval, val) set maxval to val if val is greater than maxval */ -#define maximize_( maxval, val ) {if (( maxval ) < ( val )) ( maxval )= ( val );} +#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); } /*-<a href="qh-geom.htm#TOC" >--------------------------------</a><a name="minimize_">-</a> @@ -52,7 +56,7 @@ minimize_(minval, val) set minval to val if val is less than minval */ -#define minimize_( minval, val ) {if (( minval ) > ( val )) ( minval )= ( val );} +#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); } /*-<a href="qh-geom.htm#TOC" >--------------------------------</a><a name="det2_">-</a> @@ -94,82 +98,77 @@ /*============= prototypes in alphabetical order, infrequent at end ======= */ -void qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero); -void qh_distplane (pointT *point, facetT *facet, realT *dist); -facetT *qh_findbest (pointT *point, facetT *startfacet, +void qh_backnormal(realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero); +void qh_distplane(pointT *point, facetT *facet, realT *dist); +facetT *qh_findbest(pointT *point, facetT *startfacet, boolT bestoutside, boolT isnewfacets, boolT noupper, realT *dist, boolT *isoutside, int *numpart); -facetT *qh_findbesthorizon (boolT ischeckmax, pointT *point, +facetT *qh_findbesthorizon(boolT ischeckmax, pointT *point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart); -facetT *qh_findbestnew (pointT *point, facetT *startfacet, realT *dist, +facetT *qh_findbestnew(pointT *point, facetT *startfacet, realT *dist, boolT bestoutside, boolT *isoutside, int *numpart); void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero); realT qh_getangle(pointT *vect1, pointT *vect2); pointT *qh_getcenter(setT *vertices); pointT *qh_getcentrum(facetT *facet); realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist); -void qh_normalize (coordT *normal, int dim, boolT toporient); +void qh_normalize(coordT *normal, int dim, boolT toporient); void qh_normalize2 (coordT *normal, int dim, boolT toporient, realT *minnorm, boolT *ismin); pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist); void qh_setfacetplane(facetT *newfacets); -void qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, +void qh_sethyperplane_det(int dim, coordT **rows, coordT *point0, boolT toporient, coordT *normal, realT *offset, boolT *nearzero); -void qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, +void qh_sethyperplane_gauss(int dim, coordT **rows, pointT *point0, boolT toporient, coordT *normal, coordT *offset, boolT *nearzero); -boolT qh_sharpnewfacets (void); +boolT qh_sharpnewfacets(void); /*========= infrequently used code in geom2.c =============*/ - -coordT *qh_copypoints (coordT *points, int numpoints, int dimension); -void qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]); -realT qh_determinant (realT **rows, int dim, boolT *nearzero); -realT qh_detjoggle (pointT *points, int numpoints, int dimension); -void qh_detroundoff (void); +coordT *qh_copypoints(coordT *points, int numpoints, int dimension); +void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]); +realT qh_determinant(realT **rows, int dim, boolT *nearzero); +realT qh_detjoggle(pointT *points, int numpoints, int dimension); +void qh_detroundoff(void); realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero); -realT qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp); -realT qh_distround (int dimension, realT maxabs, realT maxsumabs); +realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp); +realT qh_distround(int dimension, realT maxabs, realT maxsumabs); realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv); -realT qh_facetarea (facetT *facet); -realT qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, +realT qh_facetarea(facetT *facet); +realT qh_facetarea_simplex(int dim, coordT *apex, setT *vertices, vertexT *notvertex, boolT toporient, coordT *normal, realT *offset); -pointT *qh_facetcenter (setT *vertices); -facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, facetT **facetlist); -void qh_getarea (facetT *facetlist); +pointT *qh_facetcenter(setT *vertices); +facetT *qh_findgooddist(pointT *point, facetT *facetA, realT *distp, facetT **facetlist); +void qh_getarea(facetT *facetlist); boolT qh_gram_schmidt(int dim, realT **rows); -boolT qh_inthresholds (coordT *normal, realT *angle); -void qh_joggleinput (void); -realT *qh_maxabsval (realT *normal, int dim); +boolT qh_inthresholds(coordT *normal, realT *angle); +void qh_joggleinput(void); +realT *qh_maxabsval(realT *normal, int dim); setT *qh_maxmin(pointT *points, int numpoints, int dimension); -realT qh_maxouter (void); -void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex); -realT qh_minabsval (realT *normal, int dim); -int qh_mindiff (realT *vecA, realT *vecB, int dim); -boolT qh_orientoutside (facetT *facet); -void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane); +realT qh_maxouter(void); +void qh_maxsimplex(int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex); +realT qh_minabsval(realT *normal, int dim); +int qh_mindiff(realT *vecA, realT *vecB, int dim); +boolT qh_orientoutside(facetT *facet); +void qh_outerinner(facetT *facet, realT *outerplane, realT *innerplane); coordT qh_pointdist(pointT *point1, pointT *point2, int dim); -void qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol); -void qh_printpoints (FILE *fp, char *string, setT *points); -void qh_projectinput (void); -void qh_projectpoints (signed char *project, int n, realT *points, +void qh_printmatrix(FILE *fp, char *string, realT **rows, int numrow, int numcol); +void qh_printpoints(FILE *fp, char *string, setT *points); +void qh_projectinput(void); +void qh_projectpoints(signed char *project, int n, realT *points, int numpoints, int dim, realT *newpoints, int newdim); -int qh_rand( void); -void qh_srand( int seed); -realT qh_randomfactor (void); -void qh_randommatrix (realT *buffer, int dim, realT **row); -void qh_rotateinput (realT **rows); -void qh_rotatepoints (realT *points, int numpoints, int dim, realT **rows); -void qh_scaleinput (void); -void qh_scalelast (coordT *points, int numpoints, int dim, coordT low, +void qh_rotateinput(realT **rows); +void qh_rotatepoints(realT *points, int numpoints, int dim, realT **rows); +void qh_scaleinput(void); +void qh_scalelast(coordT *points, int numpoints, int dim, coordT low, coordT high, coordT newhigh); -void qh_scalepoints (pointT *points, int numpoints, int dim, +void qh_scalepoints(pointT *points, int numpoints, int dim, realT *newlows, realT *newhighs); -boolT qh_sethalfspace (int dim, coordT *coords, coordT **nextp, +boolT qh_sethalfspace(int dim, coordT *coords, coordT **nextp, coordT *normal, coordT *offset, coordT *feasible); -coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible); -pointT *qh_voronoi_center (int dim, setT *points); +coordT *qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible); +pointT *qh_voronoi_center(int dim, setT *points); #endif /* qhDEFgeom */ diff --git a/src/geom2.c b/src/geom2.c index 55b6d80..52296a9 100644 --- a/src/geom2.c +++ b/src/geom2.c @@ -2,52 +2,54 @@ >-------------------------------</a><a name="TOP">-</a> - geom2.c + geom2.c infrequently used geometric routines of qhull see qh-geom.htm and geom.h - copyright (c) 1993-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/geom2.c#25 $$Change: 1059 $ + $DateTime: 2009/10/30 18:26:26 $$Author: bbarber $ frequently used code goes into geom.c */ - + #include "qhull_a.h" - + /*================== functions in alphabetic order ============*/ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="copypoints">-</a> qh_copypoints( points, numpoints, dimension) - return malloc'd copy of points + return qh_malloc'd copy of points */ -coordT *qh_copypoints (coordT *points, int numpoints, int dimension) { +coordT *qh_copypoints(coordT *points, int numpoints, int dimension) { int size; coordT *newpoints; size= numpoints * dimension * sizeof(coordT); - if (!(newpoints=(coordT*)malloc(size))) { - fprintf(qh ferr, "qhull error: insufficient memory to copy %d points\n", + if (!(newpoints=(coordT*)qh_malloc(size))) { + qh_fprintf(qh ferr, 6004, "qhull error: insufficient memory to copy %d points\n", numpoints); qh_errexit(qh_ERRmem, NULL, NULL); } - memcpy ((char *)newpoints, (char *)points, size); + memcpy((char *)newpoints, (char *)points, size); return newpoints; } /* copypoints */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="crossproduct">-</a> - + qh_crossproduct( dim, vecA, vecB, vecC ) crossproduct of 2 dim vectors C= A x B - + notes: from Glasner, Graphics Gems I, p. 639 only defined for dim==3 */ -void qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]){ +void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]){ if (dim == 3) { vecC[0]= det2_(vecA[1], vecA[2], @@ -61,7 +63,7 @@ void qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]){ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="determinant">-</a> - + qh_determinant( rows, dim, nearzero ) compute signed determinant of a square matrix uses qh.NEARzero to test for degenerate matrices @@ -71,19 +73,19 @@ void qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]){ overwrites rows and the matrix if dim == 2 or 3 nearzero iff determinant < qh NEARzero[dim-1] - (not quite correct, not critical) + (!quite correct, not critical) if dim >= 4 nearzero iff diagonal[k] < qh NEARzero[k] */ -realT qh_determinant (realT **rows, int dim, boolT *nearzero) { +realT qh_determinant(realT **rows, int dim, boolT *nearzero) { realT det=0; int i; boolT sign= False; *nearzero= False; if (dim < 2) { - fprintf (qh ferr, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_fprintf(qh ferr, 6005, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n"); + qh_errexit(qh_ERRqhull, NULL, NULL); }else if (dim == 2) { det= det2_(rows[0][0], rows[0][1], rows[1][0], rows[1][1]); @@ -95,10 +97,10 @@ realT qh_determinant (realT **rows, int dim, boolT *nearzero) { 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 { + }else { qh_gausselim(rows, dim, dim, &sign, nearzero); /* if nearzero, diagonal still ok*/ det= 1.0; - for (i= dim; i--; ) + for (i=dim; i--; ) det *= (rows[i])[i]; if (sign) det= -det; @@ -108,7 +110,7 @@ realT qh_determinant (realT **rows, int dim, boolT *nearzero) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="detjoggle">-</a> - + qh_detjoggle( points, numpoints, dimension ) determine default max joggle for point array as qh_distround * qh_JOGGLEdefault @@ -122,7 +124,7 @@ realT qh_determinant (realT **rows, int dim, boolT *nearzero) { loop duplicated from qh_maxmin */ -realT qh_detjoggle (pointT *points, int numpoints, int dimension) { +realT qh_detjoggle(pointT *points, int numpoints, int dimension) { realT abscoord, distround, joggle, maxcoord, mincoord; pointT *point, *pointtemp; realT maxabs= -REALmax; @@ -130,7 +132,7 @@ realT qh_detjoggle (pointT *points, int numpoints, int dimension) { realT maxwidth= 0; int k; - for (k= 0; k < dimension; 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() */ @@ -148,19 +150,19 @@ realT qh_detjoggle (pointT *points, int numpoints, int dimension) { sumabs += abscoord; maximize_(maxabs, abscoord); } /* for k */ - distround= qh_distround (qh hull_dim, maxabs, sumabs); + distround= qh_distround(qh hull_dim, maxabs, sumabs); joggle= distround * qh_JOGGLEdefault; maximize_(joggle, REALepsilon * qh_JOGGLEdefault); - trace2((qh ferr, "qh_detjoggle: joggle=%2.2g maxwidth=%2.2g\n", joggle, maxwidth)); + trace2((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() determine maximum roundoff errors from - REALepsilon, REALmax, REALmin, qh.hull_dim, qh.MAXabs_coord, + REALepsilon, REALmax, REALmin, qh.hull_dim, qh.MAXabs_coord, qh.MAXsumcoord, qh.MAXwidth, qh.MINdenom_1 accounts for qh.SETroundoff, qh.RANDOMdist, qh MERGEexact @@ -185,17 +187,17 @@ realT qh_detjoggle (pointT *points, int numpoints, int dimension) { qh.MINoutside, qh.WIDEfacet initialize qh.max_vertex and qh.minvertex */ -void qh_detroundoff (void) { +void qh_detroundoff(void) { - qh_option ("_max-width", NULL, &qh MAXwidth); + qh_option("_max-width", NULL, &qh MAXwidth); if (!qh SETroundoff) { - qh DISTround= qh_distround (qh hull_dim, qh MAXabs_coord, qh MAXsumcoord); + qh DISTround= qh_distround(qh hull_dim, qh MAXabs_coord, qh MAXsumcoord); if (qh RANDOMdist) qh DISTround += qh RANDOMfactor * qh MAXabs_coord; - qh_option ("Error-roundoff", NULL, &qh DISTround); + qh_option("Error-roundoff", NULL, &qh DISTround); } qh MINdenom= qh MINdenom_1 * qh MAXabs_coord; - qh MINdenom_1_2= sqrt (qh MINdenom_1 * qh hull_dim) ; /* if will be normalized */ + qh MINdenom_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; @@ -203,49 +205,49 @@ void qh_detroundoff (void) { qh ANGLEround += qh RANDOMfactor; if (qh premerge_cos < REALmax/2) { qh premerge_cos -= qh ANGLEround; - if (qh RANDOMdist) - qh_option ("Angle-premerge-with-random", NULL, &qh premerge_cos); + if (qh RANDOMdist) + qh_option("Angle-premerge-with-random", NULL, &qh premerge_cos); } if (qh postmerge_cos < REALmax/2) { qh postmerge_cos -= qh ANGLEround; if (qh RANDOMdist) - qh_option ("Angle-postmerge-with-random", NULL, &qh postmerge_cos); + qh_option("Angle-postmerge-with-random", NULL, &qh postmerge_cos); } qh premerge_centrum += 2 * qh DISTround; /*2 for centrum and distplane()*/ qh postmerge_centrum += 2 * qh DISTround; if (qh RANDOMdist && (qh MERGEexact || qh PREmerge)) - qh_option ("Centrum-premerge-with-random", NULL, &qh premerge_centrum); + qh_option("Centrum-premerge-with-random", NULL, &qh premerge_centrum); if (qh RANDOMdist && qh POSTmerge) - qh_option ("Centrum-postmerge-with-random", NULL, &qh postmerge_centrum); + qh_option("Centrum-postmerge-with-random", NULL, &qh postmerge_centrum); { /* compute ONEmerge, max vertex offset for merging simplicial facets */ realT maxangle= 1.0, maxrho; - + minimize_(maxangle, qh premerge_cos); minimize_(maxangle, qh postmerge_cos); /* max diameter * sin theta + DISTround for vertex to its hyperplane */ - qh ONEmerge= sqrt (qh hull_dim) * qh MAXwidth * - sqrt (1.0 - maxangle * maxangle) + qh DISTround; + qh ONEmerge= sqrt((realT)qh hull_dim) * qh MAXwidth * + sqrt(1.0 - maxangle * maxangle) + qh DISTround; maxrho= qh hull_dim * qh premerge_centrum + qh DISTround; maximize_(qh ONEmerge, maxrho); maxrho= qh hull_dim * qh postmerge_centrum + qh DISTround; maximize_(qh ONEmerge, maxrho); if (qh MERGING) - qh_option ("_one-merge", NULL, &qh ONEmerge); + qh_option("_one-merge", NULL, &qh ONEmerge); } qh NEARinside= qh ONEmerge * qh_RATIOnearinside; /* only used if qh KEEPnearinside */ if (qh JOGGLEmax < REALmax/2 && (qh KEEPcoplanar || qh KEEPinside)) { realT maxdist; /* adjust qh.NEARinside for joggle */ - qh KEEPnearinside= True; - maxdist= sqrt (qh hull_dim) * qh JOGGLEmax + qh DISTround; + qh KEEPnearinside= True; + maxdist= sqrt((realT)qh hull_dim) * qh JOGGLEmax + qh DISTround; maxdist= 2*maxdist; /* vertex and coplanar point can joggle in opposite directions */ maximize_(qh NEARinside, maxdist); /* must agree with qh_nearcoplanar() */ } if (qh KEEPnearinside) - qh_option ("_near-inside", NULL, &qh NEARinside); + qh_option("_near-inside", NULL, &qh NEARinside); if (qh JOGGLEmax < qh DISTround) { - fprintf (qh ferr, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n", + qh_fprintf(qh ferr, 6006, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n", qh JOGGLEmax, qh DISTround); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_errexit(qh_ERRinput, NULL, NULL); } if (qh MINvisible > REALmax/2) { if (!qh MERGING) @@ -256,25 +258,25 @@ void qh_detroundoff (void) { qh MINvisible= qh_COPLANARratio * qh premerge_centrum; if (qh APPROXhull && qh MINvisible > qh MINoutside) qh MINvisible= qh MINoutside; - qh_option ("Visible-distance", NULL, &qh MINvisible); + qh_option("Visible-distance", NULL, &qh MINvisible); } if (qh MAXcoplanar > REALmax/2) { qh MAXcoplanar= qh MINvisible; - qh_option ("U-coplanar-distance", NULL, &qh MAXcoplanar); + qh_option("U-coplanar-distance", NULL, &qh MAXcoplanar); } if (!qh APPROXhull) { /* user may specify qh MINoutside */ qh MINoutside= 2 * qh MINvisible; - if (qh premerge_cos < REALmax/2) + if (qh premerge_cos < REALmax/2) maximize_(qh MINoutside, (1- qh premerge_cos) * qh MAXabs_coord); - qh_option ("Width-outside", NULL, &qh MINoutside); + qh_option("Width-outside", NULL, &qh MINoutside); } qh WIDEfacet= qh MINoutside; - maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MAXcoplanar); - maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MINvisible); - qh_option ("_wide-facet", NULL, &qh WIDEfacet); - if (qh MINvisible > qh MINoutside + 3 * REALepsilon + maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MAXcoplanar); + maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MINvisible); + qh_option("_wide-facet", NULL, &qh WIDEfacet); + if (qh MINvisible > qh MINoutside + 3 * REALepsilon && !qh BESToutside && !qh FORCEoutput) - fprintf (qh ferr, "qhull input warning: minimum visibility V%.2g is greater than \nminimum outside W%.2g. Flipped facets are likely.\n", + qh_fprintf(qh ferr, 7001, "qhull input warning: minimum visibility V%.2g is greater than \nminimum outside W%.2g. Flipped facets are likely.\n", qh MINvisible, qh MINoutside); qh max_vertex= qh DISTround; qh min_vertex= -qh DISTround; @@ -283,7 +285,7 @@ void qh_detroundoff (void) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="detsimplex">-</a> - + qh_detsimplex( apex, points, dim, nearzero ) compute determinant of a simplex with point apex and base points @@ -312,42 +314,42 @@ realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero) { rows[i++]= gmcoord; coordp= point; coorda= apex; - for (k= dim; k--; ) + for (k=dim; k--; ) *(gmcoord++)= *coordp++ - *coorda++; } if (i < dim) { - fprintf (qh ferr, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n", + qh_fprintf(qh ferr, 6007, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n", i, dim); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); } - det= qh_determinant (rows, dim, nearzero); - trace2((qh ferr, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n", - det, qh_pointid(apex), dim, *nearzero)); + det= qh_determinant(rows, dim, nearzero); + trace2((qh ferr, 2002, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n", + det, qh_pointid(apex), dim, *nearzero)); return det; } /* detsimplex */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="distnorm">-</a> - + qh_distnorm( dim, point, normal, offset ) return distance from point to hyperplane at normal/offset returns: dist - - notes: + + notes: dist > 0 if point is outside of hyperplane - + see: qh_distplane in geom.c */ -realT qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp) { +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--; ) + for (k=dim; k--; ) dist += *(coordp++) * *(normalp++); return dist; } /* distnorm */ @@ -355,7 +357,7 @@ realT qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="distround">-</a> - qh_distround ( dimension, maxabs, maxsumabs ) + qh_distround(dimension, maxabs, maxsumabs ) compute maximum round-off error for a distance computation to a normalized hyperplane maxabs is the maximum absolute value of a coordinate @@ -370,21 +372,21 @@ realT qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp) { use sqrt(dim) since one vector is normalized or use maxsumabs since one vector is < 1 */ -realT qh_distround (int dimension, realT maxabs, realT maxsumabs) { +realT qh_distround(int dimension, realT maxabs, realT maxsumabs) { realT maxdistsum, maxround; - maxdistsum= sqrt (dimension) * maxabs; + maxdistsum= sqrt((realT)dimension) * maxabs; minimize_( maxdistsum, maxsumabs); maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs); /* adds maxabs for offset */ - trace4((qh ferr, "qh_distround: %2.2g maxabs %2.2g maxsumabs %2.2g maxdistsum %2.2g\n", + trace4((qh ferr, 4008, "qh_distround: %2.2g maxabs %2.2g maxsumabs %2.2g maxdistsum %2.2g\n", maxround, maxabs, maxsumabs, maxdistsum)); return maxround; } /* distround */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="divzero">-</a> - + qh_divzero( numer, denom, mindenom1, zerodiv ) divide by a number that's nearly zero mindenom1= minimum denominator for dividing into 1.0 @@ -392,7 +394,7 @@ realT qh_distround (int dimension, realT maxabs, realT maxsumabs) { 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 @@ -403,9 +405,9 @@ realT qh_distround (int dimension, realT maxabs, realT maxsumabs) { else return 0 and zerodiv */ -realT qh_divzero (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); @@ -427,22 +429,22 @@ realT qh_divzero (realT numer, realT denom, realT mindenom1, boolT *zerodiv) { return 0.0; } } /* divzero */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="facetarea">-</a> qh_facetarea( facet ) return area for a facet - + notes: - if non-simplicial, + 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 @@ -451,7 +453,7 @@ realT qh_divzero (realT numer, realT denom, realT mindenom1, boolT *zerodiv) { compute area from centrum to ridge negate area if upper Delaunay facet */ -realT qh_facetarea (facetT *facet) { +realT qh_facetarea(facetT *facet) { vertexT *apex; pointT *centrum; realT area= 0.0; @@ -459,22 +461,22 @@ realT qh_facetarea (facetT *facet) { if (facet->simplicial) { apex= SETfirstt_(facet->vertices, vertexT); - area= qh_facetarea_simplex (qh hull_dim, apex->point, facet->vertices, + area= qh_facetarea_simplex(qh hull_dim, apex->point, facet->vertices, apex, facet->toporient, facet->normal, &facet->offset); }else { if (qh CENTERtype == qh_AScentrum) centrum= facet->center; else - centrum= qh_getcentrum (facet); - FOREACHridge_(facet->ridges) - area += qh_facetarea_simplex (qh hull_dim, centrum, ridge->vertices, + centrum= qh_getcentrum(facet); + FOREACHridge_(facet->ridges) + area += qh_facetarea_simplex(qh hull_dim, centrum, ridge->vertices, NULL, (ridge->top == facet), facet->normal, &facet->offset); if (qh CENTERtype != qh_AScentrum) - qh_memfree (centrum, qh normal_size); + qh_memfree(centrum, qh normal_size); } if (facet->upperdelaunay && qh DELAUNAY) area= -area; /* the normal should be [0,...,1] */ - trace4((qh ferr, "qh_facetarea: f%d area %2.2g\n", facet->id, area)); + trace4((qh ferr, 4009, "qh_facetarea: f%d area %2.2g\n", facet->id, area)); return area; } /* facetarea */ @@ -482,22 +484,22 @@ realT qh_facetarea (facetT *facet) { >-------------------------------</a><a name="facetarea_simplex">-</a> qh_facetarea_simplex( dim, apex, vertices, notvertex, toporient, normal, offset ) - return area for a simplex defined by + return area for a simplex defined by an apex, a base of vertices, an orientation, and a unit normal - if simplicial or tricoplanar facet, + 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 @@ -505,13 +507,13 @@ realT qh_facetarea (facetT *facet) { project simplex to normal/offset translate simplex to apex if Delaunay - set last row/column to 0 with -1 on diagonal + set last row/column to 0 with -1 on diagonal else set last row to Normal compute determinate scale and flip sign for area */ -realT qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, +realT qh_facetarea_simplex(int dim, coordT *apex, setT *vertices, vertexT *notvertex, boolT toporient, coordT *normal, realT *offset) { pointT *coorda, *coordp, *gmcoord; coordT **rows, *normalp; @@ -530,11 +532,11 @@ realT qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, coordp= vertex->point; normalp= normal; if (notvertex) { - for (k= dim; k--; ) + for (k=dim; k--; ) *(gmcoord++)= *coordp++ - *coorda++; }else { dist= *offset; - for (k= dim; k--; ) + for (k=dim; k--; ) dist += *coordp++ * *normalp++; if (dist < -qh WIDEfacet) { zinc_(Znoarea); @@ -542,64 +544,64 @@ realT qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, } coordp= vertex->point; normalp= normal; - for (k= dim; k--; ) + for (k=dim; k--; ) *(gmcoord++)= (*coordp++ - dist * *normalp++) - *coorda++; } } if (i != dim-1) { - fprintf (qh ferr, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n", + qh_fprintf(qh ferr, 6008, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n", i, dim); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); } rows[i]= gmcoord; if (qh DELAUNAY) { - for (i= 0; i < dim-1; i++) + for (i=0; i < dim-1; i++) rows[i][dim-1]= 0.0; - for (k= dim; k--; ) + for (k=dim; k--; ) *(gmcoord++)= 0.0; rows[dim-1][dim-1]= -1.0; }else { normalp= normal; - for (k= dim; k--; ) + for (k=dim; k--; ) *(gmcoord++)= *normalp++; } zinc_(Zdetsimplex); - area= qh_determinant (rows, dim, &nearzero); + area= qh_determinant(rows, dim, &nearzero); if (toporient) area= -area; area *= qh AREAfactor; - trace4((qh ferr, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n", - area, qh_pointid(apex), toporient, nearzero)); + trace4((qh ferr, 4010, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n", + area, qh_pointid(apex), toporient, nearzero)); return area; } /* facetarea_simplex */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="facetcenter">-</a> - + qh_facetcenter( vertices ) return Voronoi center (Voronoi vertex) for a facet's vertices returns: return temporary point equal to the center - + see: qh_voronoi_center() */ -pointT *qh_facetcenter (setT *vertices) { - setT *points= qh_settemp (qh_setsize (vertices)); +pointT *qh_facetcenter(setT *vertices) { + setT *points= qh_settemp(qh_setsize(vertices)); vertexT *vertex, **vertexp; pointT *center; - - FOREACHvertex_(vertices) - qh_setappend (&points, vertex->point); - center= qh_voronoi_center (qh hull_dim-1, points); - qh_settempfree (&points); + + FOREACHvertex_(vertices) + qh_setappend(&points, vertex->point); + center= qh_voronoi_center(qh hull_dim-1, points); + qh_settempfree(&points); return center; } /* facetcenter */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="findgooddist">-</a> - + qh_findgooddist( point, facetA, dist, facetlist ) find best good facet visible for point from facetA assumes facetA is visible from point @@ -608,7 +610,7 @@ pointT *qh_facetcenter (setT *vertices) { 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 @@ -624,20 +626,20 @@ pointT *qh_facetcenter (setT *vertices) { update best good neighbor if no good neighbors, update best facet */ -facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, +facetT *qh_findgooddist(pointT *point, facetT *facetA, realT *distp, facetT **facetlist) { realT bestdist= -REALmax, dist; facetT *neighbor, **neighborp, *bestfacet=NULL, *facet; - boolT goodseen= False; + boolT goodseen= False; if (facetA->good) { - zinc_(Zcheckpart); /* calls from check_bestdist occur after print stats */ - qh_distplane (point, facetA, &bestdist); + zzinc_(Zcheckpart); /* calls from check_bestdist occur after print stats */ + qh_distplane(point, facetA, &bestdist); bestfacet= facetA; goodseen= True; } - qh_removefacet (facetA); - qh_appendfacet (facetA); + qh_removefacet(facetA); + qh_appendfacet(facetA); *facetlist= facetA; facetA->visitid= ++qh visit_id; FORALLfacet_(*facetlist) { @@ -647,11 +649,11 @@ facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, neighbor->visitid= qh visit_id; if (goodseen && !neighbor->good) continue; - zinc_(Zcheckpart); - qh_distplane (point, neighbor, &dist); + zzinc_(Zcheckpart); + qh_distplane(point, neighbor, &dist); if (dist > 0) { - qh_removefacet (neighbor); - qh_appendfacet (neighbor); + qh_removefacet(neighbor); + qh_appendfacet(neighbor); if (neighbor->good) { goodseen= True; if (dist > bestdist) { @@ -664,60 +666,66 @@ facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, } if (bestfacet) { *distp= bestdist; - trace2((qh ferr, "qh_findgooddist: p%d is %2.2g above good facet f%d\n", + trace2((qh ferr, 2003, "qh_findgooddist: p%d is %2.2g above good facet f%d\n", qh_pointid(point), bestdist, bestfacet->id)); return bestfacet; } - trace4((qh ferr, "qh_findgooddist: no good facet for p%d above f%d\n", + trace4((qh ferr, 4011, "qh_findgooddist: no good facet for p%d above f%d\n", qh_pointid(point), facetA->id)); return NULL; } /* findgooddist */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="getarea">-</a> - + qh_getarea( facetlist ) set area of all facets in facetlist collect statistics + nop if hasAreaVolume returns: sets qh totarea/totvol to total area and volume of convex hull for Delaunay triangulation, computes projected area of the lower or upper hull ignores upper hull if qh ATinfinity - + notes: could compute outer volume by expanding facet area by rays from interior the following attempt at perpendicular projection underestimated badly: - qh.totoutvol += (-dist + facet->maxoutside + qh DISTround) + qh.totoutvol += (-dist + facet->maxoutside + qh DISTround) * area/ qh hull_dim; design: for each facet on facetlist compute facet->area update qh.totarea and qh.totvol */ -void qh_getarea (facetT *facetlist) { +void qh_getarea(facetT *facetlist) { realT area; realT dist; facetT *facet; + if (qh hasAreaVolume) + return; if (qh REPORTfreq) - fprintf (qh ferr, "computing area of each facet and volume of the convex hull\n"); - else - trace1((qh ferr, "qh_getarea: computing volume and area for each facet\n")); + qh_fprintf(qh ferr, 8020, "computing area of each facet and volume of the convex hull\n"); + else + trace1((qh ferr, 1001, "qh_getarea: computing volume and area for each facet\n")); qh totarea= qh totvol= 0.0; FORALLfacet_(facetlist) { if (!facet->normal) continue; if (facet->upperdelaunay && qh ATinfinity) continue; - facet->f.area= area= qh_facetarea (facet); - facet->isarea= True; + if (!facet->isarea) { + facet->f.area= qh_facetarea(facet); + facet->isarea= True; + } + area= facet->f.area; if (qh DELAUNAY) { if (facet->upperdelaunay == qh UPPERdelaunay) qh totarea += area; }else { qh totarea += area; - qh_distplane (qh interior_point, facet, &dist); + qh_distplane(qh interior_point, facet, &dist); qh totvol += -dist * area/ qh hull_dim; } if (qh PRINTstatistics) { @@ -726,11 +734,12 @@ void qh_getarea (facetT *facetlist) { wmin_(Wareamin, area); } } + qh hasAreaVolume= True; } /* getarea */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="gram_schmidt">-</a> - + qh_gram_schmidt( dim, row ) implements Gram-Schmidt orthogonalization by rows @@ -753,8 +762,8 @@ void qh_getarea (facetT *facetlist) { boolT qh_gram_schmidt(int dim, realT **row) { realT *rowi, *rowj, norm; int i, j, k; - - for(i=0; i < dim; i++) { + + for (i=0; i < dim; i++) { rowi= row[i]; for (norm= 0.0, k= dim; k--; rowi++) norm += *rowi * *rowi; @@ -762,13 +771,13 @@ boolT qh_gram_schmidt(int dim, realT **row) { 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++) { + for (k=dim; k--; ) + *(--rowi) /= norm; + for (j=i+1; j < dim; j++) { rowj= row[j]; - for(norm= 0.0, k=dim; k--; ) + for (norm= 0.0, k=dim; k--; ) norm += *rowi++ * *rowj++; - for(k=dim; k--; ) + for (k=dim; k--; ) *(--rowj) -= *(--rowi) * norm; } } @@ -778,7 +787,7 @@ boolT qh_gram_schmidt(int dim, realT **row) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="inthresholds">-</a> - + qh_inthresholds( normal, angle ) return True if normal within qh.lower_/upper_threshold @@ -786,7 +795,7 @@ boolT qh_gram_schmidt(int dim, realT **row) { estimate of angle by summing of threshold diffs angle may be NULL smaller "angle" is better - + notes: invalid if qh.SPLITthresholds @@ -798,14 +807,14 @@ boolT qh_gram_schmidt(int dim, realT **row) { for each dimension test threshold */ -boolT qh_inthresholds (coordT *normal, realT *angle) { +boolT qh_inthresholds(coordT *normal, realT *angle) { boolT within= True; int k; realT threshold; if (angle) *angle= 0.0; - for(k= 0; k < qh hull_dim; k++) { + for (k=0; k < qh hull_dim; k++) { threshold= qh lower_threshold[k]; if (threshold > -REALmax/2) { if (normal[k] < threshold) @@ -827,16 +836,16 @@ boolT qh_inthresholds (coordT *normal, realT *angle) { } return within; } /* inthresholds */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="joggleinput">-</a> - + qh_joggleinput() randomly joggle input to Qhull by qh.JOGGLEmax initial input is qh.first_point/qh.num_points of qh.hull_dim repeated calls use qh.input_points/qh.num_points - + returns: joggles points at qh.first_point/qh.num_points copies data to qh.input_points/qh.input_malloc if first time @@ -861,7 +870,7 @@ boolT qh_inthresholds (coordT *normal, realT *angle) { if qh.DELAUNAY sets the Delaunay projection */ -void qh_joggleinput (void) { +void qh_joggleinput(void) { int size, i, seed; coordT *coordp, *inputp; realT randr, randa, randb; @@ -870,15 +879,15 @@ void qh_joggleinput (void) { qh input_points= qh first_point; qh input_malloc= qh POINTSmalloc; size= qh num_points * qh hull_dim * sizeof(coordT); - if (!(qh first_point=(coordT*)malloc(size))) { - fprintf(qh ferr, "qhull error: insufficient memory to joggle %d points\n", + if (!(qh first_point=(coordT*)qh_malloc(size))) { + qh_fprintf(qh ferr, 6009, "qhull error: insufficient memory to joggle %d points\n", qh num_points); qh_errexit(qh_ERRmem, NULL, NULL); } qh POINTSmalloc= True; if (qh JOGGLEmax == 0.0) { - qh JOGGLEmax= qh_detjoggle (qh input_points, qh num_points, qh hull_dim); - qh_option ("QJoggle", NULL, &qh JOGGLEmax); + qh JOGGLEmax= qh_detjoggle(qh input_points, qh num_points, qh hull_dim); + qh_option("QJoggle", NULL, &qh JOGGLEmax); } }else { /* repeated call */ if (!qh RERUN && qh build_cnt > qh_JOGGLEretry) { @@ -886,50 +895,50 @@ void qh_joggleinput (void) { realT maxjoggle= qh MAXwidth * qh_JOGGLEmaxincrease; if (qh JOGGLEmax < maxjoggle) { qh JOGGLEmax *= qh_JOGGLEincrease; - minimize_(qh JOGGLEmax, maxjoggle); + minimize_(qh JOGGLEmax, maxjoggle); } } } - qh_option ("QJoggle", NULL, &qh JOGGLEmax); + qh_option("QJoggle", NULL, &qh JOGGLEmax); } if (qh build_cnt > 1 && qh JOGGLEmax > fmax_(qh MAXwidth/4, 0.1)) { - fprintf (qh ferr, "qhull error: the current joggle for 'QJn', %.2g, is too large for the width\nof the input. If possible, recompile Qhull with higher-precision reals.\n", + qh_fprintf(qh ferr, 6010, "qhull error: the current joggle for 'QJn', %.2g, is too large for the width\nof the input. If possible, recompile Qhull with higher-precision reals.\n", qh JOGGLEmax); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); } /* for some reason, using qh ROTATErandom and qh_RANDOMseed does not repeat the run. Use 'TRn' instead */ seed= qh_RANDOMint; - qh_option ("_joggle-seed", &seed, NULL); - trace0((qh ferr, "qh_joggleinput: joggle input by %2.2g with seed %d\n", + qh_option("_joggle-seed", &seed, NULL); + trace0((qh ferr, 6, "qh_joggleinput: joggle input by %2.2g with seed %d\n", qh JOGGLEmax, seed)); inputp= qh input_points; coordp= qh first_point; randa= 2.0 * qh JOGGLEmax/qh_RANDOMmax; randb= -qh JOGGLEmax; size= qh num_points * qh hull_dim; - for (i= size; i--; ) { + for (i=size; i--; ) { randr= qh_RANDOMint; *(coordp++)= *(inputp++) + (randr * randa + randb); } if (qh DELAUNAY) { qh last_low= qh last_high= qh last_newhigh= REALmax; - qh_setdelaunay (qh hull_dim, qh num_points, qh first_point); + qh_setdelaunay(qh hull_dim, qh num_points, qh first_point); } } /* joggleinput */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="maxabsval">-</a> - + qh_maxabsval( normal, dim ) return pointer to maximum absolute value of a dim vector returns NULL if dim=0 */ -realT *qh_maxabsval (realT *normal, int dim) { +realT *qh_maxabsval(realT *normal, int dim) { realT maxval= -REALmax; realT *maxp= NULL, *colp, absval; int k; - for (k= dim, colp= normal; k--; colp++) { + for (k=dim, colp= normal; k--; colp++) { absval= fabs_(*colp); if (absval > maxval) { maxval= absval; @@ -942,9 +951,9 @@ realT *qh_maxabsval (realT *normal, int dim) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="maxmin">-</a> - + qh_maxmin( points, numpoints, dimension ) - return max/min points for each dimension + return max/min points for each dimension determine max and min coordinates returns: @@ -984,13 +993,13 @@ setT *qh_maxmin(pointT *points, int numpoints, int dimension) { && REALmax > 0.0 && -REALmax < 0.0) ; /* all ok */ else { - fprintf (qh ferr, "qhull error: floating point constants in user.h are wrong\n\ + qh_fprintf(qh ferr, 6011, "qhull error: floating point constants in user.h are wrong\n\ REALepsilon %g REALmin %g REALmax %g -REALmax %g\n", REALepsilon, REALmin, REALmax, -REALmax); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_errexit(qh_ERRinput, NULL, NULL); } set= qh_settemp(2*dimension); - for(k= 0; k < dimension; k++) { + for (k=0; k < dimension; k++) { if (points == qh GOODpointp) minimum= maximum= points + dimension; else @@ -1020,15 +1029,15 @@ REALepsilon %g REALmin %g REALmax %g -REALmax %g\n", } maximize_(qh MAXabs_coord, maxcoord); qh MAXsumcoord += maxcoord; - qh_setappend (&set, maximum); - qh_setappend (&set, minimum); + qh_setappend(&set, maximum); + qh_setappend(&set, minimum); /* calculation of qh NEARzero is based on error formula 4.4-13 of Golub & van Loan, authors say n^3 can be ignored and 10 be used in place of rho */ qh NEARzero[k]= 80 * qh MAXsumcoord * REALepsilon; } if (qh IStracing >=1) - qh_printpoints (qh ferr, "qh_maxmin: found the max and min points (by dim):", set); + qh_printpoints(qh ferr, "qh_maxmin: found the max and min points(by dim):", set); return(set); } /* maxmin */ @@ -1042,33 +1051,33 @@ REALepsilon %g REALmin %g REALmax %g -REALmax %g\n", 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 + need to use Wnewvertexmax since could have a coplanar point for a high facet that is replaced by a low facet need to add qh.JOGGLEmax if testing input points */ -realT qh_maxouter (void) { +realT qh_maxouter(void) { realT dist; dist= fmax_(qh max_outside, qh DISTround); dist += qh DISTround; - trace4((qh ferr, "qh_maxouter: max distance from facet to outer plane is %2.2g max_outside is %2.2g\n", dist, qh max_outside)); + trace4((qh ferr, 4012, "qh_maxouter: max distance from facet to outer plane is %2.2g max_outside is %2.2g\n", dist, qh max_outside)); return dist; } /* maxouter */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="maxsimplex">-</a> - + qh_maxsimplex( dim, maxpoints, points, numpoints, simplex ) - determines maximum simplex for a set of points + 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 @@ -1082,17 +1091,17 @@ realT qh_maxouter (void) { (find points with max or min x coordinate) for each remaining dimension add point that maximizes the determinate - (use points from maxpoints first) + (use points from maxpoints first) */ -void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex) { +void qh_maxsimplex(int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex) { pointT *point, **pointp, *pointtemp, *maxpoint, *minx=NULL, *maxx=NULL; boolT nearzero, maxnearzero= False; int k, sizinit; realT maxdet= -REALmax, det, mincoord= REALmax, maxcoord= -REALmax; - sizinit= qh_setsize (*simplex); + sizinit= qh_setsize(*simplex); if (sizinit < 2) { - if (qh_setsize (maxpoints) >= 2) { + if (qh_setsize(maxpoints) >= 2) { FOREACHpoint_(maxpoints) { if (maxcoord < point[0]) { maxcoord= point[0]; @@ -1117,27 +1126,27 @@ void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, set } } } - qh_setunique (simplex, minx); - if (qh_setsize (*simplex) < 2) - qh_setunique (simplex, maxx); - sizinit= qh_setsize (*simplex); + qh_setunique(simplex, minx); + if (qh_setsize(*simplex) < 2) + qh_setunique(simplex, maxx); + sizinit= qh_setsize(*simplex); if (sizinit < 2) { - qh_precision ("input has same x coordinate"); + qh_precision("input has same x coordinate"); if (zzval_(Zsetplane) > qh hull_dim+1) { - fprintf (qh ferr, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n", + qh_fprintf(qh ferr, 6012, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n", qh_setsize(maxpoints)+numpoints); - qh_errexit (qh_ERRprec, NULL, NULL); + qh_errexit(qh_ERRprec, NULL, NULL); }else { - fprintf (qh ferr, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh hull_dim); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_fprintf(qh ferr, 6013, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh hull_dim); + qh_errexit(qh_ERRinput, NULL, NULL); } } } - for(k= sizinit; k < dim+1; k++) { + for (k=sizinit; k < dim+1; k++) { maxpoint= NULL; maxdet= -REALmax; FOREACHpoint_(maxpoints) { - if (!qh_setin (*simplex, point)) { + if (!qh_setin(*simplex, point)) { det= qh_detsimplex(point, *simplex, k, &nearzero); if ((det= fabs_(det)) > maxdet) { maxdet= det; @@ -1149,15 +1158,15 @@ void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, set if (!maxpoint || maxnearzero) { zinc_(Zsearchpoints); if (!maxpoint) { - trace0((qh ferr, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1)); + trace0((qh ferr, 7, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1)); }else { - trace0((qh ferr, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n", + trace0((qh ferr, 8, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n", k+1, qh_pointid(maxpoint), maxdet)); } FORALLpoint_(points, numpoints) { if (point == qh GOODpointp) continue; - if (!qh_setin (*simplex, point)) { + if (!qh_setin(*simplex, point)) { det= qh_detsimplex(point, *simplex, k, &nearzero); if ((det= fabs_(det)) > maxdet) { maxdet= det; @@ -1168,28 +1177,28 @@ void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, set } } /* !maxpoint */ if (!maxpoint) { - fprintf (qh ferr, "qhull internal error (qh_maxsimplex): not enough points available\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_fprintf(qh ferr, 6014, "qhull internal error (qh_maxsimplex): not enough points available\n"); + qh_errexit(qh_ERRqhull, NULL, NULL); } qh_setappend(simplex, maxpoint); - trace1((qh ferr, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n", + trace1((qh ferr, 1002, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n", qh_pointid(maxpoint), k+1, maxdet)); - } /* k */ + } /* k */ } /* maxsimplex */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="minabsval">-</a> - + qh_minabsval( normal, dim ) return minimum absolute value of a dim vector */ -realT qh_minabsval (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++) { + for (k=dim, colp=normal; k--; colp++) { maximize_(maxval, *colp); minimize_(minval, *colp); } @@ -1199,16 +1208,16 @@ realT qh_minabsval (realT *normal, int dim) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="mindiff">-</a> - - qh_mindif( vecA, vecB, dim ) + + qh_mindif ( vecA, vecB, dim ) return index of min abs. difference of two vectors */ -int qh_mindiff (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++) { + for (k=0; k < dim; k++) { diff= *vecAp++ - *vecBp++; diff= fabs_(diff); if (diff < mindiff) { @@ -1223,20 +1232,20 @@ int qh_mindiff (realT *vecA, realT *vecB, int dim) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="orientoutside">-</a> - + qh_orientoutside( facet ) make facet outside oriented via qh.interior_point returns: True if facet reversed orientation. */ -boolT qh_orientoutside (facetT *facet) { +boolT qh_orientoutside(facetT *facet) { int k; realT dist; - qh_distplane (qh interior_point, facet, &dist); + qh_distplane(qh interior_point, facet, &dist); if (dist > 0) { - for (k= qh hull_dim; k--; ) + for (k=qh hull_dim; k--; ) facet->normal[k]= -facet->normal[k]; facet->offset= -facet->offset; return True; @@ -1246,7 +1255,7 @@ boolT qh_orientoutside (facetT *facet) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="outerinner">-</a> - + qh_outerinner( facet, outerplane, innerplane ) if facet and qh.maxoutdone (i.e., qh_check_maxout) returns outer and inner plane for facet @@ -1259,11 +1268,13 @@ boolT qh_orientoutside (facetT *facet) { notes: outerplaner or innerplane may be NULL - + facet is const + Does not error (QhullFacet) + includes qh.DISTround for actual points adds another qh.DISTround if testing with floating point arithmetic */ -void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane) { +void qh_outerinner(facetT *facet, realT *outerplane, realT *innerplane) { realT dist, mindist; vertexT *vertex, **vertexp; @@ -1271,33 +1282,33 @@ void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane) { if (!qh_MAXoutside || !facet || !qh maxoutdone) { *outerplane= qh_maxouter(); /* includes qh.DISTround */ }else { /* qh_MAXoutside ... */ -#if qh_MAXoutside +#if qh_MAXoutside *outerplane= facet->maxoutside + qh DISTround; #endif - + } if (qh JOGGLEmax < REALmax/2) - *outerplane += qh JOGGLEmax * sqrt (qh hull_dim); + *outerplane += qh JOGGLEmax * sqrt((realT)qh hull_dim); } if (innerplane) { if (facet) { mindist= REALmax; FOREACHvertex_(facet->vertices) { zinc_(Zdistio); - qh_distplane (vertex->point, facet, &dist); + qh_distplane(vertex->point, facet, &dist); minimize_(mindist, dist); } *innerplane= mindist - qh DISTround; - }else + }else *innerplane= qh min_vertex - qh DISTround; if (qh JOGGLEmax < REALmax/2) - *innerplane -= qh JOGGLEmax * sqrt (qh hull_dim); + *innerplane -= qh JOGGLEmax * sqrt((realT)qh hull_dim); } } /* outerinner */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="pointdist">-</a> - + qh_pointdist( point1, point2, dim ) return distance between two points @@ -1307,7 +1318,7 @@ void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane) { 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++; @@ -1321,7 +1332,7 @@ coordT qh_pointdist(pointT *point1, pointT *point2, int dim) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="printmatrix">-</a> - + qh_printmatrix( fp, string, rows, numrow, numcol ) print matrix to fp given by row vectors print string as header @@ -1329,53 +1340,53 @@ coordT qh_pointdist(pointT *point1, pointT *point2, int dim) { notes: print a vector by qh_printmatrix(fp, "", &vect, 1, len) */ -void qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol) { +void qh_printmatrix(FILE *fp, char *string, realT **rows, int numrow, int numcol) { realT *rowp; realT r; /*bug fix*/ int i,k; - fprintf (fp, "%s\n", string); - for (i= 0; i < numrow; i++) { + qh_fprintf(fp, 9001, "%s\n", string); + for (i=0; i < numrow; i++) { rowp= rows[i]; - for (k= 0; k < numcol; k++) { + for (k=0; k < numcol; k++) { r= *rowp++; - fprintf (fp, "%6.3g ", r); + qh_fprintf(fp, 9002, "%6.3g ", r); } - fprintf (fp, "\n"); + qh_fprintf(fp, 9003, "\n"); } } /* printmatrix */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="printpoints">-</a> - + qh_printpoints( fp, string, points ) print pointids to fp for a set of points if string, prints string and 'p' point ids */ -void qh_printpoints (FILE *fp, char *string, setT *points) { +void qh_printpoints(FILE *fp, char *string, setT *points) { pointT *point, **pointp; if (string) { - fprintf (fp, "%s", string); - FOREACHpoint_(points) - fprintf (fp, " p%d", qh_pointid(point)); - fprintf (fp, "\n"); + qh_fprintf(fp, 9004, "%s", string); + FOREACHpoint_(points) + qh_fprintf(fp, 9005, " p%d", qh_pointid(point)); + qh_fprintf(fp, 9006, "\n"); }else { - FOREACHpoint_(points) - fprintf (fp, " %d", qh_pointid(point)); - fprintf (fp, "\n"); + FOREACHpoint_(points) + qh_fprintf(fp, 9007, " %d", qh_pointid(point)); + qh_fprintf(fp, 9008, "\n"); } } /* printpoints */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="projectinput">-</a> - + qh_projectinput() project input points using qh.lower_bound/upper_bound and qh DELAUNAY - if qh.lower_bound[k]=qh.upper_bound[k]= 0, - removes dimension k + if 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 @@ -1383,12 +1394,12 @@ void qh_printpoints (FILE *fp, char *string, setT *points) { returns: new point array in qh first_point of qh hull_dim coordinates sets qh POINTSmalloc - if qh DELAUNAY + if qh DELAUNAY projects points to paraboloid lowbound/highbound is also projected if qh ATinfinity adds point "at-infinity" - if qh POINTSmalloc + if qh POINTSmalloc frees old point array notes: @@ -1404,21 +1415,21 @@ void qh_printpoints (FILE *fp, char *string, setT *points) { if qh DELAUNAY if qh ATINFINITY projects points to paraboloid - computes "infinity" point as vertex average and 10% above all points + computes "infinity" point as vertex average and 10% above all points else uses qh_setdelaunay to project points to paraboloid */ -void qh_projectinput (void) { +void qh_projectinput(void) { int k,i; int newdim= qh input_dim, newnum= qh num_points; signed char *project; int size= (qh input_dim+1)*sizeof(*project); pointT *newpoints, *coord, *infinity; realT paraboloid, maxboloid= 0; - - project= (signed char*)qh_memalloc (size); - memset ((char*)project, 0, size); - for (k= 0; k < qh input_dim; k++) { /* skip Delaunay bound */ + + project= (signed char*)qh_memalloc(size); + memset((char*)project, 0, size); + for (k=0; k < qh input_dim; k++) { /* skip Delaunay bound */ if (qh lower_bound[k] == 0 && qh upper_bound[k] == 0) { project[k]= -1; newdim--; @@ -1431,32 +1442,32 @@ void qh_projectinput (void) { newnum++; } if (newdim != qh hull_dim) { - fprintf(qh ferr, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh hull_dim); + qh_fprintf(qh ferr, 6015, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh hull_dim); qh_errexit(qh_ERRqhull, NULL, NULL); } - if (!(newpoints=(coordT*)malloc(newnum*newdim*sizeof(coordT)))){ - fprintf(qh ferr, "qhull error: insufficient memory to project %d points\n", + if (!(newpoints=(coordT*)qh_malloc(newnum*newdim*sizeof(coordT)))){ + qh_fprintf(qh ferr, 6016, "qhull error: insufficient memory to project %d points\n", qh num_points); qh_errexit(qh_ERRmem, NULL, NULL); } - qh_projectpoints (project, qh input_dim+1, qh first_point, + qh_projectpoints(project, qh input_dim+1, qh first_point, qh num_points, qh input_dim, newpoints, newdim); - trace1((qh ferr, "qh_projectinput: updating lower and upper_bound\n")); - qh_projectpoints (project, qh input_dim+1, qh lower_bound, + trace1((qh ferr, 1003, "qh_projectinput: updating lower and upper_bound\n")); + qh_projectpoints(project, qh input_dim+1, qh lower_bound, 1, qh input_dim+1, qh lower_bound, newdim+1); - qh_projectpoints (project, qh input_dim+1, qh upper_bound, + qh_projectpoints(project, qh input_dim+1, qh upper_bound, 1, qh input_dim+1, qh upper_bound, newdim+1); if (qh HALFspace) { if (!qh feasible_point) { - fprintf(qh ferr, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n"); + qh_fprintf(qh ferr, 6017, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n"); qh_errexit(qh_ERRqhull, NULL, NULL); } - qh_projectpoints (project, qh input_dim, qh feasible_point, + qh_projectpoints(project, qh input_dim, qh feasible_point, 1, qh input_dim, qh feasible_point, newdim); } qh_memfree(project, ((qh input_dim+1)*sizeof(*project))); if (qh POINTSmalloc) - free (qh first_point); + qh_free(qh first_point); qh first_point= newpoints; qh POINTSmalloc= True; if (qh DELAUNAY && qh ATinfinity) { @@ -1479,20 +1490,20 @@ void qh_projectinput (void) { *(coord++) /= qh num_points; *(coord++)= maxboloid * 1.1; qh num_points++; - trace0((qh ferr, "qh_projectinput: projected points to paraboloid for Delaunay\n")); + trace0((qh ferr, 9, "qh_projectinput: projected points to paraboloid for Delaunay\n")); }else if (qh DELAUNAY) /* !qh ATinfinity */ qh_setdelaunay( qh hull_dim, qh num_points, qh first_point); } /* projectinput */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="projectpoints">-</a> - + qh_projectpoints( project, n, points, numpoints, dim, newpoints, newdim ) project points/numpoints/dim to newpoints/newdim if project[k] == -1 - delete dimension k - if project[k] == 1 + delete dimension k + if project[k] == 1 add dimension k by duplicating previous column n is size of project @@ -1506,23 +1517,23 @@ void qh_projectinput (void) { skip dimension else determine start of column in newpoints - determine start of column in points + determine start of column in points if project == +1, duplicate previous column copy dimension (column) from points to newpoints */ -void qh_projectpoints (signed char *project, int n, realT *points, +void qh_projectpoints(signed char *project, int n, realT *points, int numpoints, int dim, realT *newpoints, int newdim) { int testdim= dim, oldk=0, newk=0, i,j=0,k; realT *newp, *oldp; - - for (k= 0; k < n; k++) + + for (k=0; k < n; k++) testdim += project[k]; if (testdim != newdim) { - fprintf (qh ferr, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n", + qh_fprintf(qh ferr, 6018, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n", newdim, testdim); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); } - for (j= 0; j<n; j++) { + for (j=0; j<n; j++) { if (project[j] == -1) oldk++; else { @@ -1531,7 +1542,7 @@ void qh_projectpoints (signed char *project, int n, realT *points, if (oldk >= dim) continue; oldp= points+oldk; - }else + }else oldp= points+oldk++; for (i=numpoints; i--; ) { *newp= *oldp; @@ -1542,105 +1553,14 @@ void qh_projectpoints (signed char *project, int n, realT *points, if (oldk >= dim) break; } - trace1((qh ferr, "qh_projectpoints: projected %d points from dim %d to dim %d\n", + trace1((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="rand">-</a> - - qh_rand() - qh_srand( seed ) - generate pseudo-random number between 1 and 2^31 -2 - - notes: - from Park & Miller's minimimal standard random number generator - Communications of the ACM, 31:1192-1201, 1988. - does not use 0 or 2^31 -1 - this is silently enforced by qh_srand() - can make 'Rn' much faster by moving qh_rand to qh_distplane -*/ -int qh_rand_seed= 1; /* define as global variable instead of using qh */ - -int qh_rand( void) { -#define qh_rand_a 16807 -#define qh_rand_m 2147483647 -#define qh_rand_q 127773 /* m div a */ -#define qh_rand_r 2836 /* m mod a */ - int lo, hi, test; - int seed = qh_rand_seed; - - hi = seed / qh_rand_q; /* seed div q */ - lo = seed % qh_rand_q; /* seed mod q */ - test = qh_rand_a * lo - qh_rand_r * hi; - if (test > 0) - seed= test; - else - seed= test + qh_rand_m; - qh_rand_seed= seed; - /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */ - /* seed = qh_RANDOMmax; for testing */ - return seed; -} /* rand */ - -void qh_srand( int seed) { - if (seed < 1) - qh_rand_seed= 1; - else if (seed >= qh_rand_m) - qh_rand_seed= qh_rand_m - 1; - else - qh_rand_seed= seed; -} /* qh_srand */ - -/*-<a href="qh-geom.htm#TOC" - >-------------------------------</a><a name="randomfactor">-</a> - - qh_randomfactor() - return a random factor within qh.RANDOMmax of 1.0 - - notes: - qh.RANDOMa/b are defined in global.c -*/ -realT qh_randomfactor (void) { - realT randr; - randr= qh_RANDOMint; - return randr * qh RANDOMa + qh RANDOMb; -} /* randomfactor */ -/*-<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-geom.htm#TOC" >-------------------------------</a><a name="rotateinput">-</a> - + qh_rotateinput( rows ) rotate input using row matrix input points given by qh first_point, num_points, hull_dim @@ -1654,18 +1574,18 @@ void qh_randommatrix (realT *buffer, int dim, realT **rows) { design: see qh_rotatepoints */ -void qh_rotateinput (realT **rows) { +void qh_rotateinput(realT **rows) { if (!qh POINTSmalloc) { - qh first_point= qh_copypoints (qh first_point, qh num_points, qh hull_dim); + qh first_point= qh_copypoints(qh first_point, qh num_points, qh hull_dim); qh POINTSmalloc= True; } - qh_rotatepoints (qh first_point, qh num_points, qh hull_dim, rows); + qh_rotatepoints(qh first_point, qh num_points, qh hull_dim, rows); } /* rotateinput */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="rotatepoints">-</a> - + qh_rotatepoints( points, numpoints, dim, row ) rotate numpoints points by a d-dim row matrix assumes rows[dim] is a scratch buffer @@ -1680,30 +1600,30 @@ void qh_rotateinput (realT **rows) { for each coordinate rotate by partial inner product */ -void qh_rotatepoints (realT *points, int numpoints, int dim, realT **row) { +void qh_rotatepoints(realT *points, int numpoints, int dim, realT **row) { realT *point, *rowi, *coord= NULL, sum, *newval; int i,j,k; if (qh IStracing >= 1) - qh_printmatrix (qh ferr, "qh_rotatepoints: rotate points by", row, dim, dim); + qh_printmatrix(qh ferr, "qh_rotatepoints: rotate points by", row, dim, dim); for (point= points, j= numpoints; j--; point += dim) { newval= row[dim]; - for (i= 0; i < dim; i++) { + 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--; ) + for (k=dim; k--; ) *(--coord)= *(--newval); } -} /* rotatepoints */ - +} /* rotatepoints */ + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="scaleinput">-</a> - + qh_scaleinput() scale input points using qh low_bound/high_bound input points given by qh first_point, num_points, hull_dim @@ -1716,19 +1636,19 @@ void qh_rotatepoints (realT *points, int numpoints, int dim, realT **row) { design: see qh_scalepoints */ -void qh_scaleinput (void) { +void qh_scaleinput(void) { if (!qh POINTSmalloc) { - qh first_point= qh_copypoints (qh first_point, qh num_points, qh hull_dim); + qh first_point= qh_copypoints(qh first_point, qh num_points, qh hull_dim); qh POINTSmalloc= True; } - qh_scalepoints (qh first_point, qh num_points, qh hull_dim, + qh_scalepoints(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( points, numpoints, dim, low, high, newhigh ) scale last coordinate to [0,m] for Delaunay triangulations input points given by points, numpoints, dim @@ -1740,42 +1660,42 @@ void qh_scaleinput (void) { notes: when called by qh_setdelaunay, low/high may not match actual data - + design: compute scale and shift factors apply to last coordinate of each point */ -void qh_scalelast (coordT *points, int numpoints, int dim, coordT low, +void qh_scalelast(coordT *points, int numpoints, int dim, coordT low, coordT high, coordT newhigh) { realT scale, shift; coordT *coord; int i; boolT nearzero= False; - trace4((qh ferr, "qh_scalelast: scale last coordinate from [%2.2g, %2.2g] to [0,%2.2g]\n", + trace4((qh ferr, 4013, "qh_scalelast: scale last coordinate from [%2.2g, %2.2g] to [0,%2.2g]\n", low, high, newhigh)); qh last_low= low; qh last_high= high; qh last_newhigh= newhigh; - scale= qh_divzero (newhigh, high - low, + scale= qh_divzero(newhigh, high - low, qh MINdenom_1, &nearzero); if (nearzero) { if (qh DELAUNAY) - fprintf (qh ferr, "qhull input error: can not scale last coordinate. Input is cocircular\n or cospherical. Use option 'Qz' to add a point at infinity.\n"); + qh_fprintf(qh ferr, 6019, "qhull input error: can not scale last coordinate. Input is cocircular\n or cospherical. Use option 'Qz' to add a point at infinity.\n"); else - fprintf (qh ferr, "qhull input error: can not scale last coordinate. New bounds [0, %2.2g] are too wide for\nexisting bounds [%2.2g, %2.2g] (width %2.2g)\n", + qh_fprintf(qh ferr, 6020, "qhull input error: can not scale last coordinate. New bounds [0, %2.2g] are too wide for\nexisting bounds [%2.2g, %2.2g] (width %2.2g)\n", newhigh, low, high, high-low); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_errexit(qh_ERRinput, NULL, NULL); } shift= - low * newhigh / (high-low); coord= points + dim - 1; - for (i= numpoints; i--; coord += dim) + for (i=numpoints; i--; coord += dim) *coord= *coord * scale + shift; } /* scalelast */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="scalepoints">-</a> - + qh_scalepoints( points, numpoints, dim, newlows, newhighs ) scale points to new lowbound and highbound retains old bound when newlow= -REALmax or newhigh= +REALmax @@ -1791,20 +1711,20 @@ void qh_scalelast (coordT *points, int numpoints, int dim, coordT low, scale all points enforce new low and high bound for all points */ -void qh_scalepoints (pointT *points, int numpoints, int dim, +void qh_scalepoints(pointT *points, int numpoints, int dim, realT *newlows, realT *newhighs) { int i,k; realT shift, scale, *coord, low, high, newlow, newhigh, mincoord, maxcoord; boolT nearzero= False; - - for (k= 0; k < dim; k++) { + + 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) { + for (i=numpoints, coord=points+k; i--; coord += dim) { minimize_(low, *coord); maximize_(high, *coord); } @@ -1813,20 +1733,20 @@ void qh_scalepoints (pointT *points, int numpoints, int dim, if (newlow < -REALmax/2) newlow= low; if (qh DELAUNAY && k == dim-1 && newhigh < newlow) { - fprintf (qh ferr, "qhull input error: 'Qb%d' or 'QB%d' inverts paraboloid since high bound %.2g < low bound %.2g\n", + qh_fprintf(qh ferr, 6021, "qhull input error: 'Qb%d' or 'QB%d' inverts paraboloid since high bound %.2g < low bound %.2g\n", k, k, newhigh, newlow); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_errexit(qh_ERRinput, NULL, NULL); } - scale= qh_divzero (newhigh - newlow, high - low, + scale= qh_divzero(newhigh - newlow, high - low, qh MINdenom_1, &nearzero); if (nearzero) { - fprintf (qh ferr, "qhull input error: %d'th dimension's new bounds [%2.2g, %2.2g] too wide for\nexisting bounds [%2.2g, %2.2g]\n", + qh_fprintf(qh ferr, 6022, "qhull input error: %d'th dimension's new bounds [%2.2g, %2.2g] too wide for\nexisting bounds [%2.2g, %2.2g]\n", k, newlow, newhigh, low, high); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_errexit(qh_ERRinput, NULL, NULL); } shift= (newlow * high - low * newhigh)/(high-low); coord= points+k; - for (i= numpoints; i--; coord += dim) + for (i=numpoints; i--; coord += dim) *coord= *coord * scale + shift; coord= points+k; if (newlow < newhigh) { @@ -1836,22 +1756,22 @@ void qh_scalepoints (pointT *points, int numpoints, int dim, mincoord= newhigh; maxcoord= newlow; } - for (i= numpoints; i--; coord += dim) { + for (i=numpoints; i--; coord += dim) { minimize_(*coord, maxcoord); /* because of roundoff error */ maximize_(*coord, mincoord); } - trace0((qh ferr, "qh_scalepoints: scaled %d'th coordinate [%2.2g, %2.2g] to [%.2g, %.2g] for %d points by %2.2g and shifted %2.2g\n", + trace0((qh ferr, 10, "qh_scalepoints: scaled %d'th coordinate [%2.2g, %2.2g] to [%.2g, %.2g] for %d points by %2.2g and shifted %2.2g\n", k, low, high, newlow, newhigh, numpoints, scale, shift)); } -} /* scalepoints */ +} /* scalepoints */ + - /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="setdelaunay">-</a> - + qh_setdelaunay( dim, count, points ) project count points to dim-d paraboloid for Delaunay triangulation - + dim is one more than the dimension of the input set assumes dim is at least 3 (i.e., at least a 2-d Delaunay triangulation) @@ -1867,39 +1787,39 @@ void qh_scalepoints (pointT *points, int numpoints, int dim, for each point sets point[dim-1] to sum of squares of coordinates scale points to 'Qbb' if needed - + notes: to project one point, use - qh_setdelaunay (qh hull_dim, 1, point) - - Do not use options 'Qbk', 'QBk', or 'QbB' since they scale + qh_setdelaunay(qh hull_dim, 1, point) + + Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates after the original projection. */ -void qh_setdelaunay (int dim, int count, pointT *points) { +void qh_setdelaunay(int dim, int count, pointT *points) { int i, k; coordT *coordp, coord; realT paraboloid; - trace0((qh ferr, "qh_setdelaunay: project %d points to paraboloid for Delaunay triangulation\n", count)); + trace0((qh ferr, 11, "qh_setdelaunay: project %d points to paraboloid for Delaunay triangulation\n", count)); coordp= points; - for (i= 0; i < count; i++) { + for (i=0; i < count; i++) { coord= *coordp++; paraboloid= coord*coord; - for (k= dim-2; k--; ) { + for (k=dim-2; k--; ) { coord= *coordp++; paraboloid += coord*coord; } *coordp++ = paraboloid; } - if (qh last_low < REALmax/2) - qh_scalelast (points, count, dim, qh last_low, qh last_high, qh last_newhigh); + if (qh last_low < REALmax/2) + qh_scalelast(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( dim, coords, nextp, normal, offset, feasible ) set point to dual of halfspace relative to feasible point halfspace is normal coefficients and offset. @@ -1913,7 +1833,7 @@ void qh_setdelaunay (int dim, int count, pointT *points) { compute distance from feasible point to halfspace divide each normal coefficient by -dist */ -boolT qh_sethalfspace (int dim, coordT *coords, coordT **nextp, +boolT qh_sethalfspace(int dim, coordT *coords, coordT **nextp, coordT *normal, coordT *offset, coordT *feasible) { coordT *normp= normal, *feasiblep= feasible, *coordp= coords; realT dist; @@ -1922,103 +1842,103 @@ boolT qh_sethalfspace (int dim, coordT *coords, coordT **nextp, boolT zerodiv; dist= *offset; - for (k= dim; k--; ) + for (k=dim; k--; ) dist += *(normp++) * *(feasiblep++); if (dist > 0) goto LABELerroroutside; normp= normal; if (dist < -qh MINdenom) { - for (k= dim; k--; ) + for (k=dim; k--; ) *(coordp++)= *(normp++) / -dist; }else { - for (k= dim; k--; ) { - *(coordp++)= qh_divzero (*(normp++), -dist, qh MINdenom_1, &zerodiv); - if (zerodiv) + for (k=dim; k--; ) { + *(coordp++)= qh_divzero(*(normp++), -dist, qh MINdenom_1, &zerodiv); + if (zerodiv) goto LABELerroroutside; } } *nextp= coordp; if (qh IStracing >= 4) { - fprintf (qh ferr, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset); - for (k= dim, coordp= coords; k--; ) { + qh_fprintf(qh ferr, 8021, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset); + for (k=dim, coordp=coords; k--; ) { r= *coordp++; - fprintf (qh ferr, " %6.2g", r); + qh_fprintf(qh ferr, 8022, " %6.2g", r); } - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 8023, "\n"); } return True; LABELerroroutside: feasiblep= feasible; normp= normal; - fprintf(qh ferr, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: "); - for (k= dim; k--; ) - fprintf (qh ferr, qh_REAL_1, r=*(feasiblep++)); - fprintf (qh ferr, "\n halfspace: "); - for (k= dim; k--; ) - fprintf (qh ferr, qh_REAL_1, r=*(normp++)); - fprintf (qh ferr, "\n at offset: "); - fprintf (qh ferr, qh_REAL_1, *offset); - fprintf (qh ferr, " and distance: "); - fprintf (qh ferr, qh_REAL_1, dist); - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 6023, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: "); + for (k=dim; k--; ) + qh_fprintf(qh ferr, 8024, qh_REAL_1, r=*(feasiblep++)); + qh_fprintf(qh ferr, 8025, "\n halfspace: "); + for (k=dim; k--; ) + qh_fprintf(qh ferr, 8026, qh_REAL_1, r=*(normp++)); + qh_fprintf(qh ferr, 8027, "\n at offset: "); + qh_fprintf(qh ferr, 8028, qh_REAL_1, *offset); + qh_fprintf(qh ferr, 8029, " and distance: "); + qh_fprintf(qh ferr, 8030, qh_REAL_1, dist); + qh_fprintf(qh ferr, 8031, "\n"); return False; } /* sethalfspace */ /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="sethalfspace_all">-</a> - + qh_sethalfspace_all( dim, count, halfspaces, feasible ) generate dual for halfspace intersection with feasible point array of count halfspaces - each halfspace is normal coefficients followed by offset + 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 + 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 + If using option 'Fp', also set qh feasible_point. It is a malloc'd array that is freed by qh_freebuffers. design: see qh_sethalfspace */ -coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible) { +coordT *qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible) { int i, newdim; pointT *newpoints; coordT *coordp, *normalp, *offsetp; - trace0((qh ferr, "qh_sethalfspace_all: compute dual for halfspace intersection\n")); + trace0((qh ferr, 12, "qh_sethalfspace_all: compute dual for halfspace intersection\n")); newdim= dim - 1; - if (!(newpoints=(coordT*)malloc(count*newdim*sizeof(coordT)))){ - fprintf(qh ferr, "qhull error: insufficient memory to compute dual of %d halfspaces\n", + if (!(newpoints=(coordT*)qh_malloc(count*newdim*sizeof(coordT)))){ + qh_fprintf(qh ferr, 6024, "qhull error: insufficient memory to compute dual of %d halfspaces\n", count); qh_errexit(qh_ERRmem, NULL, NULL); } coordp= newpoints; normalp= halfspaces; - for (i= 0; i < count; i++) { + for (i=0; i < count; i++) { offsetp= normalp + newdim; - if (!qh_sethalfspace (newdim, coordp, &coordp, normalp, offsetp, feasible)) { - fprintf (qh ferr, "The halfspace was at index %d\n", i); - qh_errexit (qh_ERRinput, NULL, NULL); + if (!qh_sethalfspace(newdim, coordp, &coordp, normalp, offsetp, feasible)) { + qh_fprintf(qh ferr, 8032, "The halfspace was at index %d\n", i); + qh_errexit(qh_ERRinput, NULL, NULL); } normalp= offsetp + 1; } return newpoints; } /* sethalfspace_all */ - + /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="sharpnewfacets">-</a> - + qh_sharpnewfacets() returns: true if could be an acute angle (facets in different quadrants) - + notes: for qh_findbest @@ -2027,18 +1947,18 @@ coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *fea if two facets are in different quadrants set issharp */ -boolT qh_sharpnewfacets () { +boolT qh_sharpnewfacets() { facetT *facet; boolT issharp = False; int *quadrant, k; - - quadrant= (int*)qh_memalloc (qh hull_dim * sizeof(int)); + + quadrant= (int*)qh_memalloc(qh hull_dim * sizeof(int)); FORALLfacet_(qh newfacet_list) { if (facet == qh newfacet_list) { - for (k= qh hull_dim; k--; ) + for (k=qh hull_dim; k--; ) quadrant[ k]= (facet->normal[ k] > 0); }else { - for (k= qh hull_dim; k--; ) { + for (k=qh hull_dim; k--; ) { if (quadrant[ k] != (facet->normal[ k] > 0)) { issharp= True; break; @@ -2049,13 +1969,13 @@ boolT qh_sharpnewfacets () { break; } qh_memfree( quadrant, qh hull_dim * sizeof(int)); - trace3((qh ferr, "qh_sharpnewfacets: %d\n", issharp)); + trace3((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( dim, points ) return Voronoi center for a set of points dim is the orginal dimension of the points @@ -2063,7 +1983,7 @@ boolT qh_sharpnewfacets () { returns: center as a temporary point - if non-simplicial, + if non-simplicial, returns center for max simplex of points notes: @@ -2077,9 +1997,9 @@ boolT qh_sharpnewfacets () { compute determinate compute Voronoi center (see Bowyer & Woodwark) */ -pointT *qh_voronoi_center (int dim, setT *points) { +pointT *qh_voronoi_center(int dim, setT *points) { pointT *point, **pointp, *point0; - pointT *center= (pointT*)qh_memalloc (qh center_size); + pointT *center= (pointT*)qh_memalloc(qh center_size); setT *simplex; int i, j, k, size= qh_setsize(points); coordT *gmcoord; @@ -2089,12 +2009,13 @@ pointT *qh_voronoi_center (int dim, setT *points) { if (size == dim+1) simplex= points; else if (size < dim+1) { - fprintf (qh ferr, "qhull internal error (qh_voronoi_center):\n need at least %d points to construct a Voronoi center\n", + qh_fprintf(qh ferr, 6025, "qhull internal error (qh_voronoi_center):\n need at least %d points to construct a Voronoi center\n", dim+1); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); + simplex= points; /* never executed -- avoids warning */ }else { - simplex= qh_settemp (dim+1); - qh_maxsimplex (dim, points, NULL, 0, &simplex); + simplex= qh_settemp(dim+1); + qh_maxsimplex(dim, points, NULL, 0, &simplex); } point0= SETfirstt_(simplex, pointT); gmcoord= qh gm_matrix; @@ -2108,19 +2029,19 @@ pointT *qh_voronoi_center (int dim, setT *points) { sum2row= gmcoord; for (i=0; i < dim; i++) { sum2= 0.0; - for (k= 0; k < dim; k++) { + for (k=0; k < dim; k++) { diffp= qh gm_row[k] + i; sum2 += *diffp * *diffp; } *(gmcoord++)= sum2; } - det= qh_determinant (qh gm_row, dim, &nearzero); - factor= qh_divzero (0.5, det, qh MINdenom, &infinite); + det= qh_determinant(qh gm_row, dim, &nearzero); + factor= qh_divzero(0.5, det, qh MINdenom, &infinite); if (infinite) { for (k=dim; k--; ) center[k]= qh_INFINITE; if (qh IStracing) - qh_printpoints (qh ferr, "qh_voronoi_center: at infinity for ", simplex); + qh_printpoints(qh ferr, "qh_voronoi_center: at infinity for ", simplex); }else { for (i=0; i < dim; i++) { gmcoord= qh gm_matrix; @@ -2128,7 +2049,7 @@ pointT *qh_voronoi_center (int dim, setT *points) { for (k=0; k < dim; k++) { qh gm_row[k]= gmcoord; if (k == i) { - for (j= dim; j--; ) + for (j=dim; j--; ) *(gmcoord++)= *sum2p++; }else { FOREACHpoint_(simplex) { @@ -2137,24 +2058,24 @@ pointT *qh_voronoi_center (int dim, setT *points) { } } } - center[i]= qh_determinant (qh gm_row, dim, &nearzero)*factor + point0[i]; + center[i]= qh_determinant(qh gm_row, dim, &nearzero)*factor + point0[i]; } #ifndef qh_NOtrace if (qh IStracing >= 3) { - fprintf (qh ferr, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor); - qh_printmatrix (qh ferr, "center:", ¢er, 1, dim); + qh_fprintf(qh ferr, 8033, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor); + qh_printmatrix(qh ferr, "center:", ¢er, 1, dim); if (qh IStracing >= 5) { - qh_printpoints (qh ferr, "points", simplex); + qh_printpoints(qh ferr, "points", simplex); FOREACHpoint_(simplex) - fprintf (qh ferr, "p%d dist %.2g, ", qh_pointid (point), - qh_pointdist (point, center, dim)); - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 8034, "p%d dist %.2g, ", qh_pointid(point), + qh_pointdist(point, center, dim)); + qh_fprintf(qh ferr, 8035, "\n"); } } #endif } if (simplex != points) - qh_settempfree (&simplex); + qh_settempfree(&simplex); return center; } /* voronoi_center */ diff --git a/src/global.c b/src/global.c index ff0cafb..44156f9 100644 --- a/src/global.c +++ b/src/global.c @@ -1,3 +1,4 @@ + /*<html><pre> -<a href="qh-globa.htm" >-------------------------------</a><a name="TOP">-</a> @@ -6,16 +7,20 @@ see README - see qhull.h for qh.globals and function prototypes + see qhulllib.h for qh.globals and function prototypes see qhull_a.h for internal functions - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/global.c#45 $$Change: 1096 $ + $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ */ #include "qhull_a.h" -/*========= qh definition (see qhull.h) =======================*/ +/*========= qh definition -- globals defined in qhulllib.h =======================*/ + +int qhull_inuse= 0; /* not used */ #if qh_QHpointer qhT *qh_qh= NULL; /* pointer to all global variables */ @@ -39,7 +44,7 @@ qhT qh_qh; /* all global variables. 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, qhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c + recompile user_eg.c, rbox.c, qhulllib.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c */ char *qh_version = "2003.1 2003/12/30"; @@ -50,7 +55,7 @@ char *qh_version = "2003.1 2003/12/30"; qh_appendprint( printFormat ) append printFormat to qh.PRINTout unless already defined */ -void qh_appendprint (qh_PRINT format) { +void qh_appendprint(qh_PRINT format) { int i; for (i=0; i < qh_PRINTEND; i++) { @@ -82,13 +87,14 @@ void qh_checkflags(char *command, char *hiddenflags) { char chkkey[]= " "; char chkopt[]= " "; char chkopt2[]= " "; + boolT waserr= False; if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') { - fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags); + 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")) { - fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags); + 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 */ @@ -102,13 +108,8 @@ void qh_checkflags(char *command, char *hiddenflags) { break; key = *s++; chkerr = NULL; - if (key == '\'') { /* TO 'file name' */ - t= strchr(s, '\''); - if (!t) { - fprintf(qh ferr, "qhull error (qh_checkflags): missing the 2nd single-quote for:\n%s\n", s-1); - qh_errexit(qh_ERRinput, NULL, NULL); - } - s= t+1; + if (key == 'T' && (*s == 'I' || *s == 'O')) { /* TI or TO 'file name' */ + s= qh_skipfilename(++s); continue; } chkkey[1]= key; @@ -137,7 +138,7 @@ void qh_checkflags(char *command, char *hiddenflags) { if (strstr(hiddenflags, chkopt)) chkerr= chkopt; }else { - qh_strtod (s-1, &t); + qh_strtod(s-1, &t); if (s < t) s= t; } @@ -147,12 +148,81 @@ void qh_checkflags(char *command, char *hiddenflags) { if (chkerr) { *chkerr= '\''; chkerr[strlen(chkerr)-1]= '\''; - fprintf(qh ferr, "qhull error: option %s is not used with this program.\n It may be used with qhull.\n", chkerr); - qh_errexit(qh_ERRinput, NULL, NULL); + 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> @@ -164,7 +234,7 @@ void qh_checkflags(char *command, char *hiddenflags) { use first value to determine time 0 from Stevens '92 8.15 */ -unsigned long qh_clock (void) { +unsigned long qh_clock(void) { #if (qh_CLOCKtype == 2) struct tms time; @@ -173,21 +243,21 @@ unsigned long qh_clock (void) { unsigned long ticks; if (!clktck) { - if ((clktck= sysconf (_SC_CLK_TCK)) < 0) { - fprintf (qh ferr, "qhull internal error (qh_clock): sysconf() failed. Use qh_CLOCKtype 1 in user.h\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + if ((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) { - fprintf (qh ferr, "qhull internal error (qh_clock): times() 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 - fprintf (qh ferr, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); /* never returns */ + 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 */ @@ -201,46 +271,46 @@ unsigned long qh_clock (void) { notes: must match qh_initbuffers() */ -void qh_freebuffers (void) { +void qh_freebuffers(void) { - trace5((qh ferr, "qh_freebuffers: freeing up global memory buffers\n")); + 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_memfree(qh NEARzero, qh hull_dim * sizeof(realT)); + qh_memfree(qh lower_threshold, (qh input_dim+1) * sizeof(realT)); + qh_memfree(qh upper_threshold, (qh input_dim+1) * sizeof(realT)); + qh_memfree(qh lower_bound, (qh input_dim+1) * sizeof(realT)); + qh_memfree(qh upper_bound, (qh input_dim+1) * sizeof(realT)); + qh_memfree(qh gm_matrix, (qh hull_dim+1) * qh hull_dim * sizeof(coordT)); + qh_memfree(qh gm_row, (qh hull_dim+1) * sizeof(coordT *)); qh NEARzero= qh lower_threshold= qh upper_threshold= NULL; qh lower_bound= qh upper_bound= NULL; qh gm_matrix= NULL; qh gm_row= NULL; - qh_setfree (&qh other_points); - qh_setfree (&qh del_vertices); - qh_setfree (&qh coplanarset); + 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 */ - free (qh line); + qh_free(qh line); if (qh half_space) - free (qh half_space); + qh_free(qh half_space); if (qh temp_malloc) - free (qh temp_malloc); + qh_free(qh temp_malloc); if (qh feasible_point) /* allocated by qh_readfeasible */ - free (qh feasible_point); + qh_free(qh feasible_point); if (qh feasible_string) /* allocated by qh_initflags */ - free (qh feasible_string); + 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) { - free(qh first_point); + qh_free(qh first_point); qh first_point= NULL; } if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */ - free (qh input_points); + qh_free(qh input_points); qh input_points= NULL; } - trace5((qh ferr, "qh_freebuffers: finished\n")); + trace5((qh ferr, 5002, "qh_freebuffers: finished\n")); } /* freebuffers */ @@ -250,7 +320,7 @@ void qh_freebuffers (void) { qh_freebuild( allmem ) free global memory used by qh_initbuild and qh_buildhull if !allmem, - does not free short memory (freed by qh_memfreeshort) + does not free short memory (e.g., facetT, freed by qh_memfreeshort) design: free centrums @@ -265,28 +335,27 @@ void qh_freebuffers (void) { free merge set free temporary sets */ -void qh_freebuild (boolT allmem) { +void qh_freebuild(boolT allmem) { facetT *facet; vertexT *vertex; ridgeT *ridge, **ridgep; mergeT *merge, **mergep; - trace1((qh ferr, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n")); + 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); + qh_settruncate(qh del_vertices, 0); if (allmem) { - qh_clearcenters (qh_ASnone); while ((vertex= qh vertex_list)) { if (vertex->next) - qh_delvertex (vertex); + qh_delvertex(vertex); else { - qh_memfree (vertex, sizeof(vertexT)); + qh_memfree(vertex, sizeof(vertexT)); qh newvertex_list= qh vertex_list= NULL; } } }else if (qh VERTEXneighbors) { FORALLvertices - qh_setfreelong (&(vertex->neighbors)); + qh_setfreelong(&(vertex->neighbors)); } qh VERTEXneighbors= False; qh GOODclosest= NULL; @@ -311,34 +380,34 @@ void qh_freebuild (boolT allmem) { }else ridge->seen= True; } - qh_setfree (&(facet->outsideset)); - qh_setfree (&(facet->coplanarset)); - qh_setfree (&(facet->neighbors)); - qh_setfree (&(facet->ridges)); - qh_setfree (&(facet->vertices)); + 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); + qh_delfacet(facet); else { - qh_memfree (facet, sizeof(facetT)); + qh_memfree(facet, sizeof(facetT)); qh visible_list= qh newfacet_list= qh facet_list= NULL; } } }else { FORALLfacets { - qh_setfreelong (&(facet->outsideset)); - qh_setfreelong (&(facet->coplanarset)); + qh_setfreelong(&(facet->outsideset)); + qh_setfreelong(&(facet->coplanarset)); if (!facet->simplicial) { - qh_setfreelong (&(facet->neighbors)); - qh_setfreelong (&(facet->ridges)); - qh_setfreelong (&(facet->vertices)); + 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_setfree(&(qh hash_table)); + qh_memfree(qh interior_point, qh normal_size); qh interior_point= NULL; FOREACHmerge_(qh facet_mergeset) /* usually empty */ - qh_memfree (merge, sizeof(mergeT)); + qh_memfree(merge, sizeof(mergeT)); qh facet_mergeset= NULL; /* temp set */ qh degen_mergeset= NULL; /* temp set */ qh_settempfree_all(); @@ -348,33 +417,51 @@ void qh_freebuild (boolT allmem) { >-------------------------------</a><a name="freeqhull">-</a> qh_freeqhull( allmem ) - free global memory - if !allmem, - does not free short memory (freed by qh_memfreeshort) + 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 +} - notes: - sets qh.NOerrexit in case caller forgets to +/*-<a href="qh-globa.htm#TOC" +>-------------------------------</a><a name="freeqhull2">-</a> - design: - free global and temporary memory from qh_initbuild and qh_buildhull - free buffers - free statistics +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_freeqhull (boolT allmem) { +void qh_freeqhull2(boolT allmem) { - trace1((qh ferr, "qh_freeqhull: free global memory\n")); - qh NOerrexit= True; /* no more setjmp since called at exit */ - qh_freebuild (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 - free (qh_qh); - qh_qh= NULL; + memset((char *)qh_qh, 0, sizeof(qhT)); + /* qh_qh freed by caller, qh_freeqhull() */ #else memset((char *)&qh_qh, 0, sizeof(qhT)); - qh NOerrexit= True; #endif -} /* freeqhull */ + qh NOerrexit= True; +} /* freeqhull2 */ /*-<a href="qh-globa.htm#TOC" >-------------------------------</a><a name="init_A">-</a> @@ -394,10 +481,10 @@ void qh_freeqhull (boolT allmem) { 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); +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" @@ -412,7 +499,7 @@ void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv points[dim] is the first coordinate of the second point ismalloc=True - Qhull will call free(points) on exit or input transformation + 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 @@ -441,29 +528,29 @@ void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv 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); +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); + 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); + 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++) { + 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); + qh_gram_schmidt(qh hull_dim, qh gm_row); + qh_rotateinput(qh gm_row); } } /* init_B */ @@ -474,7 +561,7 @@ void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc) { build qh.qhull_command from argc/argv returns: - a space-deliminated string of options (just as typed) + a space-delimited string of options (just as typed) notes: makes option string easy to input and output @@ -482,27 +569,9 @@ void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc) { argc/argv may be 0/NULL */ void qh_init_qhull_command(int argc, char *argv[]) { - int i; - char *s; - - if (argc) { - if ((s= strrchr( argv[0], '\\'))) /* Borland gives full path */ - strcpy (qh qhull_command, s+1); - else - strcpy (qh qhull_command, argv[0]); - if ((s= strstr (qh qhull_command, ".EXE")) - || (s= strstr (qh qhull_command, ".exe"))) - *s= '\0'; - } - for (i=1; i < argc; i++) { - if (strlen (qh qhull_command) + strlen(argv[i]) + 1 < sizeof(qh qhull_command)) { - strcat (qh qhull_command, " "); - strcat (qh qhull_command, argv[i]); - }else { - fprintf (qh ferr, "qhull input error: more than %d characters in command line\n", - (int)sizeof(qh qhull_command)); - exit (1); /* can not use qh_errexit */ - } + + if (!qh_argv_to_command(argc, argv, qh qhull_command, sizeof(qh qhull_command))){ + qh_exit(qh_ERRinput); /* error reported, can not use qh_errexit */ } } /* init_qhull_command */ @@ -534,8 +603,6 @@ void qh_init_qhull_command(int argc, char *argv[]) { check syntax append approriate option to option string set appropriate global variable or append printFormat to print options - - */ void qh_initflags(char *command) { int k, i, lastproject; @@ -543,12 +610,14 @@ void qh_initflags(char *command) { boolT isgeom= False, wasproject; realT r; - if (command != &qh qhull_command[0]) { - *qh qhull_command= '\0'; - strncat( qh qhull_command, command, sizeof( qh qhull_command)); + 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)); + } + while (*s && !isspace(*s)) /* skip program name */ + s++; } - while (*s && !isspace(*s)) /* skip program name */ - s++; while (*s) { while (*s && isspace(*s)) s++; @@ -559,53 +628,53 @@ void qh_initflags(char *command) { prev_s= s; switch (*s++) { case 'd': - qh_option ("delaunay", NULL, NULL); + qh_option("delaunay", NULL, NULL); qh DELAUNAY= True; break; case 'f': - qh_option ("facets", NULL, NULL); - qh_appendprint (qh_PRINTfacets); + qh_option("facets", NULL, NULL); + qh_appendprint(qh_PRINTfacets); break; case 'i': - qh_option ("incidence", NULL, NULL); - qh_appendprint (qh_PRINTincidences); + qh_option("incidence", NULL, NULL); + qh_appendprint(qh_PRINTincidences); break; case 'm': - qh_option ("mathematica", NULL, NULL); - qh_appendprint (qh_PRINTmathematica); + qh_option("mathematica", NULL, NULL); + qh_appendprint(qh_PRINTmathematica); break; case 'n': - qh_option ("normals", NULL, NULL); - qh_appendprint (qh_PRINTnormals); + qh_option("normals", NULL, NULL); + qh_appendprint(qh_PRINTnormals); break; case 'o': - qh_option ("offFile", NULL, NULL); - qh_appendprint (qh_PRINToff); + qh_option("offFile", NULL, NULL); + qh_appendprint(qh_PRINToff); break; case 'p': - qh_option ("points", NULL, NULL); - qh_appendprint (qh_PRINTpoints); + qh_option("points", NULL, NULL); + qh_appendprint(qh_PRINTpoints); break; case 's': - qh_option ("summary", NULL, NULL); + qh_option("summary", NULL, NULL); qh PRINTsummary= True; break; case 'v': - qh_option ("voronoi", NULL, NULL); + qh_option("voronoi", NULL, NULL); qh VORONOI= True; qh DELAUNAY= True; break; case 'A': if (!isdigit(*s) && *s != '.' && *s != '-') - fprintf(qh ferr, "qhull warning: no maximum cosine angle given for option 'An'. Ignored.\n"); + 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_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_cos= qh_strtod(s, &s); + qh_option("Angle-postmerge", NULL, &qh postmerge_cos); qh POSTmerge= True; } qh MERGING= True; @@ -613,15 +682,15 @@ void qh_initflags(char *command) { break; case 'C': if (!isdigit(*s) && *s != '.' && *s != '-') - fprintf(qh ferr, "qhull warning: no centrum radius given for option 'Cn'. Ignored.\n"); + 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_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_centrum= qh_strtod(s, &s); + qh_option("Centrum-postmerge", NULL, &qh postmerge_centrum); qh POSTmerge= True; } qh MERGING= True; @@ -629,184 +698,184 @@ void qh_initflags(char *command) { break; case 'E': if (*s == '-') - fprintf(qh ferr, "qhull warning: negative maximum roundoff given for option 'An'. Ignored.\n"); + qh_fprintf(qh ferr, 7004, "qhull warning: negative maximum roundoff given for option 'An'. Ignored.\n"); else if (!isdigit(*s)) - fprintf(qh ferr, "qhull warning: no maximum roundoff given for option 'En'. Ignored.\n"); + 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 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); + qh_strtod(s, &t); while (t > s) { - if (*t && !isspace (*t)) { + if (*t && !isspace(*t)) { if (*t == ',') t++; else - fprintf (qh ferr, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n"); + qh_fprintf(qh ferr, 7006, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n"); } s= t; - qh_strtod (s, &t); + qh_strtod(s, &t); } if (start < t) { - if (!(qh feasible_string= (char*)calloc (t-start+1, 1))) { - fprintf(qh ferr, "qhull error: insufficient memory for 'Hn,n,n'\n"); + if (!(qh feasible_string= (char*)calloc(t-start+1, 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, t-start); - qh_option ("Halfspace-about", NULL, NULL); - qh_option (qh feasible_string, NULL, NULL); + strncpy(qh feasible_string, start, t-start); + qh_option("Halfspace-about", NULL, NULL); + qh_option(qh feasible_string, NULL, NULL); }else - qh_option ("Halfspace", NULL, NULL); + qh_option("Halfspace", NULL, NULL); break; case 'R': if (!isdigit(*s)) - fprintf(qh ferr, "qhull warning: missing random perturbation for option 'Rn'. Ignored\n"); + 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 RANDOMfactor= qh_strtod(s, &s); + qh_option("Random_perturb", NULL, &qh RANDOMfactor); qh RANDOMdist= True; } break; case 'V': if (!isdigit(*s) && *s != '-') - fprintf(qh ferr, "qhull warning: missing visible distance for option 'Vn'. Ignored\n"); + 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); + qh MINvisible= qh_strtod(s, &s); + qh_option("Visible", NULL, &qh MINvisible); } break; case 'U': if (!isdigit(*s) && *s != '-') - fprintf(qh ferr, "qhull warning: missing coplanar distance for option 'Un'. Ignored\n"); + 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); + qh MAXcoplanar= qh_strtod(s, &s); + qh_option("U-coplanar", NULL, &qh MAXcoplanar); } break; case 'W': if (*s == '-') - fprintf(qh ferr, "qhull warning: negative outside width for option 'Wn'. Ignored.\n"); + qh_fprintf(qh ferr, 7010, "qhull warning: negative outside width for option 'Wn'. Ignored.\n"); else if (!isdigit(*s)) - fprintf(qh ferr, "qhull warning: missing outside width for option 'Wn'. Ignored\n"); + 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 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++) { + switch (*s++) { case 'a': - qh_option ("Farea", NULL, NULL); - qh_appendprint (qh_PRINTarea); + qh_option("Farea", NULL, NULL); + qh_appendprint(qh_PRINTarea); qh GETarea= True; break; case 'A': - qh_option ("FArea-total", NULL, NULL); + qh_option("FArea-total", NULL, NULL); qh GETarea= True; break; case 'c': - qh_option ("Fcoplanars", NULL, NULL); - qh_appendprint (qh_PRINTcoplanars); + qh_option("Fcoplanars", NULL, NULL); + qh_appendprint(qh_PRINTcoplanars); break; case 'C': - qh_option ("FCentrums", NULL, NULL); - qh_appendprint (qh_PRINTcentrums); + qh_option("FCentrums", NULL, NULL); + qh_appendprint(qh_PRINTcentrums); break; case 'd': - qh_option ("Fd-cdd-in", NULL, NULL); + qh_option("Fd-cdd-in", NULL, NULL); qh CDDinput= True; break; case 'D': - qh_option ("FD-cdd-out", NULL, NULL); + qh_option("FD-cdd-out", NULL, NULL); qh CDDoutput= True; break; case 'F': - qh_option ("FFacets-xridge", NULL, NULL); - qh_appendprint (qh_PRINTfacets_xridge); + qh_option("FFacets-xridge", NULL, NULL); + qh_appendprint(qh_PRINTfacets_xridge); break; case 'i': - qh_option ("Finner", NULL, NULL); - qh_appendprint (qh_PRINTinner); + qh_option("Finner", NULL, NULL); + qh_appendprint(qh_PRINTinner); break; case 'I': - qh_option ("FIDs", NULL, NULL); - qh_appendprint (qh_PRINTids); + qh_option("FIDs", NULL, NULL); + qh_appendprint(qh_PRINTids); break; case 'm': - qh_option ("Fmerges", NULL, NULL); - qh_appendprint (qh_PRINTmerges); + qh_option("Fmerges", NULL, NULL); + qh_appendprint(qh_PRINTmerges); break; case 'M': - qh_option ("FMaple", NULL, NULL); - qh_appendprint (qh_PRINTmaple); + qh_option("FMaple", NULL, NULL); + qh_appendprint(qh_PRINTmaple); break; case 'n': - qh_option ("Fneighbors", NULL, NULL); - qh_appendprint (qh_PRINTneighbors); + qh_option("Fneighbors", NULL, NULL); + qh_appendprint(qh_PRINTneighbors); break; case 'N': - qh_option ("FNeighbors-vertex", NULL, NULL); - qh_appendprint (qh_PRINTvneighbors); + qh_option("FNeighbors-vertex", NULL, NULL); + qh_appendprint(qh_PRINTvneighbors); break; case 'o': - qh_option ("Fouter", NULL, NULL); - qh_appendprint (qh_PRINTouter); + qh_option("Fouter", NULL, NULL); + qh_appendprint(qh_PRINTouter); break; case 'O': if (qh PRINToptions1st) { - qh_option ("FOptions", NULL, NULL); - qh_appendprint (qh_PRINToptions); + 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); + qh_option("Fpoint-intersect", NULL, NULL); + qh_appendprint(qh_PRINTpointintersect); break; case 'P': - qh_option ("FPoint-nearest", NULL, NULL); - qh_appendprint (qh_PRINTpointnearest); + qh_option("FPoint-nearest", NULL, NULL); + qh_appendprint(qh_PRINTpointnearest); break; case 'Q': - qh_option ("FQhull", NULL, NULL); - qh_appendprint (qh_PRINTqhull); + qh_option("FQhull", NULL, NULL); + qh_appendprint(qh_PRINTqhull); break; case 's': - qh_option ("Fsummary", NULL, NULL); - qh_appendprint (qh_PRINTsummary); + qh_option("Fsummary", NULL, NULL); + qh_appendprint(qh_PRINTsummary); break; case 'S': - qh_option ("FSize", NULL, NULL); - qh_appendprint (qh_PRINTsize); + qh_option("FSize", NULL, NULL); + qh_appendprint(qh_PRINTsize); qh GETarea= True; break; case 't': - qh_option ("Ftriangles", NULL, NULL); - qh_appendprint (qh_PRINTtriangles); + qh_option("Ftriangles", NULL, NULL); + qh_appendprint(qh_PRINTtriangles); break; case 'v': /* option set in qh_initqhull_globals */ - qh_appendprint (qh_PRINTvertices); + qh_appendprint(qh_PRINTvertices); break; case 'V': - qh_option ("FVertex-average", NULL, NULL); - qh_appendprint (qh_PRINTaverage); + qh_option("FVertex-average", NULL, NULL); + qh_appendprint(qh_PRINTaverage); break; case 'x': - qh_option ("Fxtremes", NULL, NULL); - qh_appendprint (qh_PRINTextremes); + qh_option("Fxtremes", NULL, NULL); + qh_appendprint(qh_PRINTextremes); break; default: s--; - fprintf (qh ferr, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]); + qh_fprintf(qh ferr, 7012, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]); while (*++s && !isspace(*s)); break; } @@ -814,63 +883,63 @@ void qh_initflags(char *command) { break; case 'G': isgeom= True; - qh_appendprint (qh_PRINTgeom); + qh_appendprint(qh_PRINTgeom); while (*s && !isspace(*s)) { - switch(*s++) { + switch (*s++) { case 'a': - qh_option ("Gall-points", NULL, NULL); + qh_option("Gall-points", NULL, NULL); qh PRINTdots= True; break; case 'c': - qh_option ("Gcentrums", NULL, NULL); + qh_option("Gcentrums", NULL, NULL); qh PRINTcentrums= True; break; case 'h': - qh_option ("Gintersections", NULL, NULL); + qh_option("Gintersections", NULL, NULL); qh DOintersections= True; break; case 'i': - qh_option ("Ginner", NULL, NULL); + qh_option("Ginner", NULL, NULL); qh PRINTinner= True; break; case 'n': - qh_option ("Gno-planes", NULL, NULL); + qh_option("Gno-planes", NULL, NULL); qh PRINTnoplanes= True; break; case 'o': - qh_option ("Gouter", NULL, NULL); + qh_option("Gouter", NULL, NULL); qh PRINTouter= True; break; case 'p': - qh_option ("Gpoints", NULL, NULL); + qh_option("Gpoints", NULL, NULL); qh PRINTcoplanar= True; break; case 'r': - qh_option ("Gridges", NULL, NULL); + qh_option("Gridges", NULL, NULL); qh PRINTridges= True; break; case 't': - qh_option ("Gtransparent", NULL, NULL); + qh_option("Gtransparent", NULL, NULL); qh PRINTtransparent= True; break; case 'v': - qh_option ("Gvertices", NULL, NULL); + qh_option("Gvertices", NULL, NULL); qh PRINTspheres= True; break; case 'D': - if (!isdigit (*s)) - fprintf (qh ferr, "qhull input error: missing dimension for option 'GDn'\n"); + if (!isdigit(*s)) + qh_fprintf(qh ferr, 6035, "qhull input error: missing dimension for option 'GDn'\n"); else { if (qh DROPdim >= 0) - fprintf (qh ferr, "qhull warning: can only drop one dimension. Previous 'GD%d' ignored\n", + qh_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); + qh DROPdim= qh_strtol(s, &s); + qh_option("GDrop-dim", &qh DROPdim, NULL); } break; default: s--; - fprintf (qh ferr, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]); + qh_fprintf(qh ferr, 7014, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]); while (*++s && !isspace(*s)); break; } @@ -878,65 +947,65 @@ void qh_initflags(char *command) { break; case 'P': while (*s && !isspace(*s)) { - switch(*s++) { + switch (*s++) { case 'd': case 'D': /* see qh_initthresholds() */ key= s[-1]; - i= qh_strtol (s, &s); + i= qh_strtol(s, &s); r= 0; if (*s == ':') { s++; - r= qh_strtod (s, &s); + r= qh_strtod(s, &s); } if (key == 'd') - qh_option ("Pdrop-facets-dim-less", &i, &r); + qh_option("Pdrop-facets-dim-less", &i, &r); else - qh_option ("PDrop-facets-dim-more", &i, &r); + qh_option("PDrop-facets-dim-more", &i, &r); break; case 'g': - qh_option ("Pgood-facets", NULL, NULL); + qh_option("Pgood-facets", NULL, NULL); qh PRINTgood= True; break; case 'G': - qh_option ("PGood-facet-neighbors", NULL, NULL); + qh_option("PGood-facet-neighbors", NULL, NULL); qh PRINTneighbors= True; break; case 'o': - qh_option ("Poutput-forced", NULL, NULL); + qh_option("Poutput-forced", NULL, NULL); qh FORCEoutput= True; break; case 'p': - qh_option ("Pprecision-ignore", NULL, NULL); + qh_option("Pprecision-ignore", NULL, NULL); qh PRINTprecision= False; break; case 'A': - if (!isdigit (*s)) - fprintf (qh ferr, "qhull input error: missing facet count for keep area option 'PAn'\n"); + 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 KEEParea= qh_strtol(s, &s); + qh_option("PArea-keep", &qh KEEParea, NULL); qh GETarea= True; } break; case 'F': - if (!isdigit (*s)) - fprintf (qh ferr, "qhull input error: missing facet area for option 'PFn'\n"); + 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 KEEPminArea= qh_strtod(s, &s); + qh_option("PFacet-area-keep", NULL, &qh KEEPminArea); qh GETarea= True; } break; case 'M': - if (!isdigit (*s)) - fprintf (qh ferr, "qhull input error: missing merge count for option 'PMn'\n"); + 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); + qh KEEPmerge= qh_strtol(s, &s); + qh_option("PMerge-keep", &qh KEEPmerge, NULL); } break; default: s--; - fprintf (qh ferr, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]); + qh_fprintf(qh ferr, 7015, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]); while (*++s && !isspace(*s)); break; } @@ -945,23 +1014,23 @@ void qh_initflags(char *command) { case 'Q': lastproject= -1; while (*s && !isspace(*s)) { - switch(*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); + qh_option("QbBound-unit-box", NULL, &r); break; } if (key == 'b' && *s == 'b') { s++; qh SCALElast= True; - qh_option ("Qbbound-last", NULL, NULL); + qh_option("Qbbound-last", NULL, NULL); break; } - k= qh_strtol (s, &s); + k= qh_strtol(s, &s); r= 0.0; wasproject= False; if (*s == ':') { @@ -970,12 +1039,12 @@ void qh_initflags(char *command) { t= s; /* need true dimension for memory allocation */ while (*t && !isspace(*t)) { if (toupper(*t++) == 'B' - && k == qh_strtol (t, &t) + && k == qh_strtol(t, &t) && *t++ == ':' && qh_strtod(t, &t) == 0.0) { qh PROJECTinput++; - trace2((qh ferr, "qh_initflags: project dimension %d\n", k)); - qh_option ("Qb-project-dim", &k, NULL); + trace2((qh ferr, 2004, "qh_initflags: project dimension %d\n", k)); + qh_option("Qb-project-dim", &k, NULL); wasproject= True; lastproject= k; break; @@ -990,148 +1059,148 @@ void qh_initflags(char *command) { qh SCALEinput= True; if (r == 0.0) r= -qh_DEFAULTbox; - qh_option ("Qbound-dim-low", &k, &r); + 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); + qh_option("QBound-dim-high", &k, &r); } } break; case 'c': - qh_option ("Qcoplanar-keep", NULL, NULL); + qh_option("Qcoplanar-keep", NULL, NULL); qh KEEPcoplanar= True; break; case 'f': - qh_option ("Qfurthest-outside", NULL, NULL); + qh_option("Qfurthest-outside", NULL, NULL); qh BESToutside= True; break; case 'g': - qh_option ("Qgood-facets-only", NULL, NULL); + qh_option("Qgood-facets-only", NULL, NULL); qh ONLYgood= True; break; case 'i': - qh_option ("Qinterior-keep", NULL, NULL); + qh_option("Qinterior-keep", NULL, NULL); qh KEEPinside= True; break; case 'm': - qh_option ("Qmax-outside-only", NULL, NULL); + qh_option("Qmax-outside-only", NULL, NULL); qh ONLYmax= True; break; case 'r': - qh_option ("Qrandom-outside", NULL, NULL); + qh_option("Qrandom-outside", NULL, NULL); qh RANDOMoutside= True; break; case 's': - qh_option ("Qsearch-initial-simplex", NULL, NULL); + qh_option("Qsearch-initial-simplex", NULL, NULL); qh ALLpoints= True; break; case 't': - qh_option ("Qtriangulate", NULL, NULL); + qh_option("Qtriangulate", NULL, NULL); qh TRIangulate= True; break; case 'T': - qh_option ("QTestPoints", NULL, NULL); - if (!isdigit (*s)) - fprintf (qh ferr, "qhull input error: missing number of test points for option 'QTn'\n"); + 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); + qh TESTpoints= qh_strtol(s, &s); + qh_option("QTestPoints", &qh TESTpoints, NULL); } break; case 'u': - qh_option ("QupperDelaunay", NULL, NULL); + qh_option("QupperDelaunay", NULL, NULL); qh UPPERdelaunay= True; break; case 'v': - qh_option ("Qvertex-neighbors-convex", NULL, NULL); + qh_option("Qvertex-neighbors-convex", NULL, NULL); qh TESTvneighbors= True; break; case 'x': - qh_option ("Qxact-merge", NULL, NULL); + qh_option("Qxact-merge", NULL, NULL); qh MERGEexact= True; break; case 'z': - qh_option ("Qz-infinity-point", NULL, NULL); + qh_option("Qz-infinity-point", NULL, NULL); qh ATinfinity= True; break; case '0': - qh_option ("Q0-no-premerge", NULL, NULL); + 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_option("Q1-no-angle-sort", NULL, NULL); qh ANGLEmerge= False; break; } - switch(*s++) { + switch (*s++) { case '0': - qh_option ("Q10-no-narrow", NULL, NULL); + qh_option("Q10-no-narrow", NULL, NULL); qh NOnarrow= True; break; case '1': - qh_option ("Q11-trinormals Qtriangulate", NULL, NULL); + qh_option("Q11-trinormals Qtriangulate", NULL, NULL); qh TRInormals= True; qh TRIangulate= True; break; default: s--; - fprintf (qh ferr, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]); + 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_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_option("Q3-no-merge-vertices", NULL, NULL); qh MERGEvertices= False; LABELcheckdigit: if (isdigit(*s)) - fprintf (qh ferr, "qhull warning: can not follow '1', '2', or '3' with a digit. '%c' skipped.\n", + 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_option("Q4-avoid-old-into-new", NULL, NULL); qh AVOIDold= True; break; case '5': - qh_option ("Q5-no-check-outer", NULL, NULL); + qh_option("Q5-no-check-outer", NULL, NULL); qh SKIPcheckmax= True; break; case '6': - qh_option ("Q6-no-concave-merge", NULL, NULL); + qh_option("Q6-no-concave-merge", NULL, NULL); qh SKIPconvex= True; break; case '7': - qh_option ("Q7-no-breadth-first", NULL, NULL); + qh_option("Q7-no-breadth-first", NULL, NULL); qh VIRTUALmemory= True; break; case '8': - qh_option ("Q8-no-near-inside", NULL, NULL); + qh_option("Q8-no-near-inside", NULL, NULL); qh NOnearinside= True; break; case '9': - qh_option ("Q9-pick-furthest", NULL, NULL); + qh_option("Q9-pick-furthest", NULL, NULL); qh PICKfurthest= True; break; case 'G': - i= qh_strtol (s, &t); + i= qh_strtol(s, &t); if (qh GOODpoint) - fprintf (qh ferr, "qhull warning: good point already defined for option 'QGn'. Ignored\n"); + qh_fprintf(qh ferr, 7018, "qhull warning: good point already defined for option 'QGn'. Ignored\n"); else if (s == t) - fprintf (qh ferr, "qhull warning: missing good point id for option 'QGn'. Ignored\n"); + 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); + qh_option("QGood-if-dont-see-point", &i, NULL); }else { qh GOODpoint= i+1; - qh_option ("QGood-if-see-point", &i, NULL); + qh_option("QGood-if-see-point", &i, NULL); } s= t; break; @@ -1139,39 +1208,39 @@ void qh_initflags(char *command) { if (!isdigit(*s) && *s != '-') qh JOGGLEmax= 0.0; else { - qh JOGGLEmax= (realT) qh_strtod (s, &s); - qh_option ("QJoggle", NULL, &qh JOGGLEmax); + qh JOGGLEmax= (realT) qh_strtod(s, &s); + qh_option("QJoggle", NULL, &qh JOGGLEmax); } break; case 'R': if (!isdigit(*s) && *s != '-') - fprintf (qh ferr, "qhull warning: missing random seed for option 'QRn'. Ignored\n"); + 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 ); + qh_option("QRotate-id", &i, NULL ); else if (i < -1) - qh_option ("QRandom-seed", &i, NULL ); + qh_option("QRandom-seed", &i, NULL ); } break; case 'V': - i= qh_strtol (s, &t); + i= qh_strtol(s, &t); if (qh GOODvertex) - fprintf (qh ferr, "qhull warning: good vertex already defined for option 'QVn'. Ignored\n"); + qh_fprintf(qh ferr, 7021, "qhull warning: good vertex already defined for option 'QVn'. Ignored\n"); else if (s == t) - fprintf (qh ferr, "qhull warning: no good point id given for option 'QVn'. Ignored\n"); + 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); + qh_option("QV-good-facets-not-point", &i, NULL); }else { - qh_option ("QV-good-facets-point", &i, NULL); + qh_option("QV-good-facets-point", &i, NULL); qh GOODvertex= i + 1; } s= t; break; default: s--; - fprintf (qh ferr, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]); + qh_fprintf(qh ferr, 7023, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]); while (*++s && !isspace(*s)); break; } @@ -1181,180 +1250,162 @@ void qh_initflags(char *command) { while (*s && !isspace(*s)) { if (isdigit(*s) || *s == '-') qh IStracing= qh_strtol(s, &s); - else switch(*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_option("Tcheck-frequently", NULL, NULL); qh CHECKfrequently= True; break; case 's': - qh_option ("Tstatistics", NULL, NULL); + qh_option("Tstatistics", NULL, NULL); qh PRINTstatistics= True; break; case 'v': - qh_option ("Tverify", NULL, NULL); + qh_option("Tverify", NULL, NULL); qh VERIFYoutput= True; break; case 'z': - if (!qh fout) - fprintf (qh ferr, "qhull warning: output file undefined (stdout). Option 'Tz' ignored.\n"); + 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_option("Tz-stdout", NULL, NULL); + qh USEstdout= True; qh ferr= qh fout; qhmem.ferr= qh fout; } break; case 'C': if (!isdigit(*s)) - fprintf (qh ferr, "qhull warning: missing point id for cone for trace option 'TCn'. Ignored\n"); + 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); + i= qh_strtol(s, &s); + qh_option("TCone-stop", &i, NULL); qh STOPcone= i + 1; } break; case 'F': if (!isdigit(*s)) - fprintf (qh ferr, "qhull warning: missing frequency count for trace option 'TFn'. Ignored\n"); + 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 REPORTfreq= qh_strtol(s, &s); + qh_option("TFacet-log", &qh REPORTfreq, NULL); qh REPORTfreq2= qh REPORTfreq/2; /* for tracemerging() */ } break; case 'I': - if (s[0] != ' ' || s[1] == '\"' || s[1] == '\'' ||isspace (s[1])) { - s++; - fprintf (qh ferr, "qhull warning: option 'TI' mistyped.\nUse 'TI', one space, file name, and space or end-of-line.\nDo not use quotes. Option 'FI' ignored.\n"); - }else { /* not a procedure because of qh_option (filename, NULL, NULL); */ - char filename[500], *t= filename; - - s++; - while (*s) { - if (t - filename >= sizeof (filename)-2) { - fprintf (qh ferr, "qhull error: filename for 'TI' too long.\n"); - qh_errexit (qh_ERRinput, NULL, NULL); - } - if (isspace (*s)) - break; - *(t++)= *s++; - } - *t= '\0'; - if (!freopen (filename, "r", stdin)) { - fprintf (qh ferr, "qhull error: could not open file \"%s\".", filename); - qh_errexit (qh_ERRinput, NULL, NULL); + 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, 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); + qh_option("TInput-file", NULL, NULL); + qh_option(filename, NULL, NULL); } - } + } break; case 'O': - if (s[0] != ' ' || s[1] == '\"' || isspace (s[1])) { - s++; - fprintf (qh ferr, "qhull warning: option 'TO' mistyped.\nUse 'TO', one space, file name, and space or end-of-line.\nThe file name may be enclosed in single quotes.\nDo not use double quotes. Option 'FO' ignored.\n"); - }else { /* not a procedure because of qh_option (filename, NULL, NULL); */ - char filename[500], *t= filename; - boolT isquote= False; - - s++; - if (*s == '\'') { - isquote= True; - s++; - } - while (*s) { - if (t - filename >= sizeof (filename)-2) { - fprintf (qh ferr, "qhull error: filename for 'TO' too long.\n"); - qh_errexit (qh_ERRinput, NULL, NULL); - } - if (isquote) { - if (*s == '\'') { - s++; - isquote= False; - break; - } - }else if (isspace (*s)) - break; - *(t++)= *s++; - } - *t= '\0'; - if (isquote) - fprintf (qh ferr, "qhull error: missing end quote for option 'TO'. Rest of line ignored.\n"); - else if (!freopen (filename, "w", stdout)) { - fprintf (qh ferr, "qhull error: could not open file \"%s\".", filename); - qh_errexit (qh_ERRinput, NULL, NULL); - }else { - qh_option ("TOutput-file", NULL, NULL); - qh_option (filename, NULL, NULL); + 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, 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)) - fprintf (qh ferr, "qhull warning: missing point id for trace option 'TPn'. Ignored\n"); + 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); + qh TRACEpoint= qh_strtol(s, &s); + qh_option("Trace-point", &qh TRACEpoint, NULL); } break; case 'M': if (!isdigit(*s)) - fprintf (qh ferr, "qhull warning: missing merge id for trace option 'TMn'. Ignored\n"); + 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); + qh TRACEmerge= qh_strtol(s, &s); + qh_option("Trace-merge", &qh TRACEmerge, NULL); } break; case 'R': if (!isdigit(*s)) - fprintf (qh ferr, "qhull warning: missing rerun count for trace option 'TRn'. Ignored\n"); + 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); + qh RERUN= qh_strtol(s, &s); + qh_option("TRerun", &qh RERUN, NULL); } break; case 'V': - i= qh_strtol (s, &t); + i= qh_strtol(s, &t); if (s == t) - fprintf (qh ferr, "qhull warning: missing furthest point id for trace option 'TVn'. Ignored\n"); + 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); + qh_option("TV-stop-before-point", &i, NULL); }else { qh STOPpoint= i + 1; - qh_option ("TV-stop-after-point", &i, NULL); + qh_option("TV-stop-after-point", &i, NULL); } s= t; break; case 'W': if (!isdigit(*s)) - fprintf (qh ferr, "qhull warning: missing max width for trace option 'TWn'. Ignored\n"); + 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); + qh TRACEdist= (realT) qh_strtod(s, &s); + qh_option("TWide-trace", NULL, &qh TRACEdist); } break; default: s--; - fprintf (qh ferr, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]); + 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: - fprintf (qh ferr, "qhull warning: unknown flag %c (%x)\n", (int)s[-1], + 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)) { - fprintf (qh ferr, "qhull warning: missing space after flag %c (%x); reserved for menu. Skipped.\n", + 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 (isgeom && !qh FORCEoutput && qh PRINTout[1]) - fprintf (qh ferr, "qhull warning: additional output formats are not compatible with Geomview\n"); + qh_fprintf(qh ferr, 7037, "qhull warning: additional output formats are not compatible with Geomview\n"); /* set derived values in qh_initqhull_globals */ } /* initflags */ @@ -1368,21 +1419,21 @@ void qh_initflags(char *command) { notes: must match qh_freebuffers() */ -void qh_initqhull_buffers (void) { +void qh_initqhull_buffers(void) { int k; - qh TEMPsize= (qhmem.LASTsize - sizeof (setT))/SETelemsize; + qh TEMPsize= (qhmem.LASTsize - sizeof(setT))/SETelemsize; if (qh TEMPsize <= 0 || qh TEMPsize > qhmem.LASTsize) qh TEMPsize= 8; /* e.g., if qh_NOmem */ - qh other_points= qh_setnew (qh TEMPsize); - qh del_vertices= qh_setnew (qh TEMPsize); - qh coplanarset= qh_setnew (qh TEMPsize); + qh 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--; ) { + 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; @@ -1417,21 +1468,19 @@ void qh_initqhull_buffers (void) { initialize points array from input arguments test for qh.ZEROcentrum (i.e., use opposite vertex instead of cetrum for convexity testing) - test for qh.PRINTgood (i.e., only print 'good' facets) initialize qh.CENTERtype, qh.normal_size, qh.center_size, qh.TRACEpoint/level, initialize and test random numbers - check for conflicting print output options + qh_initqhull_outputflags() -- adjust and test output flags */ -void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc) { +void qh_initqhull_globals(coordT *points, int numpoints, int dim, boolT ismalloc) { int seed, pointsneeded, extra= 0, i, randi, k; - boolT printgeom= False, printmath= False, printcoplanar= False; realT randr; realT factorial; time_t timedata; - trace0((qh ferr, "qh_initqhull_globals: for %s | %s\n", qh rbox_command, + trace0((qh ferr, 13, "qh_initqhull_globals: for %s | %s\n", qh rbox_command, qh qhull_command)); qh POINTSmalloc= ismalloc; qh first_point= points; @@ -1441,10 +1490,10 @@ void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismallo qh MERGING= True; if (qh hull_dim <= 4) { qh PREmerge= True; - qh_option ("_pre-merge", NULL, NULL); + qh_option("_pre-merge", NULL, NULL); }else { qh MERGEexact= True; - qh_option ("Qxact_merge", NULL, NULL); + qh_option("Qxact_merge", NULL, NULL); } }else if (qh MERGEexact) qh MERGING= True; @@ -1454,51 +1503,44 @@ void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismallo #endif } if (qh TRIangulate && qh JOGGLEmax < REALmax/2 && qh PRINTprecision) - fprintf(qh ferr, "qhull warning: joggle ('QJ') always produces simplicial output. Triangulated output ('Qt') does nothing.\n"); + 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); + 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); + qh_option("_zero-centrum", NULL, NULL); } if (qh JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh PRINTprecision) - fprintf(qh ferr, "qhull warning: real epsilon, %2.2g, is probably too large for joggle ('QJn')\nRecompile with double precision reals (see user.h).\n", + 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) { - fprintf (qh ferr, "qhull input error: merging not installed (qh_NOmerge + 'Qx', 'Cn' or 'An')\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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 PRINTgood || qh PRINTneighbors)) { - if (qh KEEParea || qh KEEPminArea < REALmax/2 || qh KEEPmerge || qh DELAUNAY - || (!qh ONLYgood && (qh GOODvertex || qh GOODpoint))) { - qh PRINTgood= True; - qh_option ("Pgood", NULL, NULL); - } - } if (qh DELAUNAY && qh KEEPcoplanar && !qh KEEPinside) { qh KEEPinside= True; - qh_option ("Qinterior-keep", NULL, NULL); + qh_option("Qinterior-keep", NULL, NULL); } if (qh DELAUNAY && qh HALFspace) { - fprintf (qh ferr, "qhull input error: can not use Delaunay ('d') or Voronoi ('v') with halfspace intersection ('H')\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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)) { - fprintf (qh ferr, "qhull input error: use upper-Delaunay ('Qu') or infinity-point ('Qz') with Delaunay ('d') or Voronoi ('v')\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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) { - fprintf (qh ferr, "qhull input error: can not use infinity-point ('Qz') with upper-Delaunay ('Qu')\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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) - fprintf (qh ferr, "qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n"); + 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); @@ -1507,38 +1549,39 @@ void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismallo else if (qh VORONOI) qh CENTERtype= qh_ASvoronoi; if (qh TESTvneighbors && !qh MERGING) { - fprintf(qh ferr, "qhull input error: test vertex neighbors ('Qv') needs a merge option\n"); - qh_errexit (qh_ERRinput, NULL ,NULL); + 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++; - extra= 1; + if (qh ATinfinity) + extra= 1; } } if (qh hull_dim <= 1) { - fprintf(qh ferr, "qhull error: dimension %d must be > 1\n", qh hull_dim); - qh_errexit (qh_ERRinput, NULL, NULL); + 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++) + for (k=2, factorial=1.0; k < qh hull_dim; k++) factorial *= k; qh AREAfactor= 1.0 / factorial; - trace2((qh ferr, "qh_initqhull_globals: initialize globals. dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n", + 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); + qh_option("Q3-no-merge-vertices-dim-high", NULL, NULL); } if (qh GOODpoint) pointsneeded++; #ifdef qh_NOtrace if (qh IStracing) { - fprintf (qh ferr, "qhull input error: tracing is not installed (qh_NOtrace in user.h)"); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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) { @@ -1550,12 +1593,12 @@ void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismallo qh IStracing= 0; } if (qh ROTATErandom == 0 || qh ROTATErandom == -1) { - seed= time (&timedata); + seed= (int)time(&timedata); if (qh ROTATErandom == -1) { seed= -seed; - qh_option ("QRandom-seed", &seed, NULL ); + qh_option("QRandom-seed", &seed, NULL ); }else - qh_option ("QRotate-random", &seed, NULL); + qh_option("QRotate-random", &seed, NULL); qh ROTATErandom= seed; } seed= qh ROTATErandom; @@ -1565,47 +1608,118 @@ void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismallo seed= -seed; qh_RANDOMseed_(seed); randr= 0.0; - for (i= 1000; i--; ) { + for (i=1000; i--; ) { randi= qh_RANDOMint; randr += randi; if (randi > qh_RANDOMmax) { - fprintf (qh ferr, "\ + qh_fprintf(qh ferr, 8036, "\ qhull configuration error (qh_RANDOMmax in user.h):\n\ - random integer %d > qh_RANDOMmax (%.8g)\n", + random integer %d > qh_RANDOMmax(%.8g)\n", randi, qh_RANDOMmax); - qh_errexit (qh_ERRinput, NULL, NULL); + qh_errexit(qh_ERRinput, NULL, NULL); } } qh_RANDOMseed_(seed); randr = randr/1000; - if (randr < qh_RANDOMmax/10 - || randr > qh_RANDOMmax * 5) - fprintf (qh ferr, "\ + 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/2.0, qh_RANDOMmax); + 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) { - fprintf(qh ferr, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1. Qhull uses linear hash probing\n", + qh_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); + qh_errexit(qh_ERRqhull, NULL, NULL); } if (numpoints+extra < pointsneeded) { - fprintf(qh ferr,"qhull input error: not enough points (%d) to construct initial simplex (need %d)\n", + 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(sizeof(vertexT)); + if (qh MERGING) { + qh_memsize(sizeof(ridgeT)); + qh_memsize(sizeof(mergeT)); + } + qh_memsize(sizeof(facetT)); + i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize; /* ridge.vertices */ + qh_memsize(i); + qh_memsize(qh normal_size); /* normal */ + i += SETelemsize; /* facet.vertices, .ridges, .neighbors */ + qh_memsize(i); + qh_user_memsizes(); + qh_memsetup(); +} /* initqhull_mem */ + +/*-<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) { - fprintf(qh ferr,"qhull input error: transparent Delaunay ('Gt') needs 3-d Delaunay ('d') w/o 'GDn'\n"); + 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--; ) { + 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) @@ -1615,135 +1729,120 @@ qhull configuration warning (qh_RANDOMmax in user.h):\n\ else if (qh PRINTout[i] == qh_PRINTpointnearest) printcoplanar= True; else if (qh PRINTout[i] == qh_PRINTpointintersect && !qh HALFspace) { - fprintf (qh ferr, "qhull input error: option 'Fp' is only used for \nhalfspace intersection ('Hn,n,n').\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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)) { - fprintf (qh ferr, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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) { - fprintf (qh ferr, "qhull input error: option 'FC' is not available for Voronoi vertices ('v')\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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); + qh_option("Fvoronoi", NULL, NULL); else - qh_option ("Fvertices", NULL, NULL); + qh_option("Fvertices", NULL, NULL); } } if (printcoplanar && qh DELAUNAY && qh JOGGLEmax < REALmax/2) { if (qh PRINTprecision) - fprintf (qh ferr, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n"); + qh_fprintf(qh ferr, 7041, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n"); } - if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood) { - if ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar) { - qh KEEPcoplanar = True; - qh_option ("Qcoplanar", NULL, NULL); - } + if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood + && ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar)) { + qh_fprintf(qh ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' not set for qhull.\n"); } if (printmath && (qh hull_dim > 3 || qh VORONOI)) { - fprintf (qh ferr, "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); + 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) { - fprintf (qh ferr, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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)) { - fprintf (qh ferr, "qhull input error: no output specified for Geomview\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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)) { - fprintf (qh ferr, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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)) { - fprintf (qh ferr, "qhull input warning: coplanars, vertices, and centrums output not\n\ -available for 4-d output (ignored). Could use 'GDn' instead.\n"); + qh_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) { + 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) - fprintf (qh ferr, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh DROPdim); + 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; } -} /* initqhull_globals */ - -/*-<a href="qh-globa.htm#TOC" - >-------------------------------</a><a name="initqhull_mem">-</a> +} /* qh_initqhull_outputflags */ - 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 +/*-<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_mem (void) { - int numsizes; - int i; +void qh_initqhull_start(FILE *infile, FILE *outfile, FILE *errfile) { - numsizes= 8+10; - qh_meminitbuffers (qh IStracing, qh_MEMalign, numsizes, - qh_MEMbufsize,qh_MEMinitbuf); - qh_memsize(sizeof(vertexT)); - if (qh MERGING) { - qh_memsize(sizeof(ridgeT)); - qh_memsize(sizeof(mergeT)); +#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 */ } - qh_memsize(sizeof(facetT)); - i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize; /* ridge.vertices */ - qh_memsize(i); - qh_memsize(qh normal_size); /* normal */ - i += SETelemsize; /* facet.vertices, .ridges, .neighbors */ - qh_memsize(i); - qh_user_memsizes(); - qh_memsetup(); -} /* initqhull_mem */ + 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_start">-</a> + >-------------------------------</a><a name="initqhull_start2">-</a> - qh_initqhull_start( infile, outfile, errfile ) + 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_start (FILE *infile, FILE *outfile, FILE *errfile) { +void qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile) { + time_t timedata; + int seed; - qh_CPUclock; /* start the clock */ + qh_CPUclock; /* start the clock(for qh_clock). One-shot. */ #if qh_QHpointer - if (!(qh_qh= (qhT *)malloc (sizeof(qhT)))) { - fprintf (errfile, "qhull error (qh_initqhull_globals): insufficient memory\n"); - exit (qh_ERRmem); /* no error handler */ - } memset((char *)qh_qh, 0, sizeof(qhT)); /* every field is 0, FALSE, NULL */ #else memset((char *)&qh_qh, 0, sizeof(qhT)); #endif - strcat (qh qhull, "qhull"); - qh_initstatistics(); qh ANGLEmerge= True; qh DROPdim= -1; qh ferr= errfile; @@ -1780,8 +1879,12 @@ void qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile) { qh TRACEpoint= -1; /* recompile or use 'TPn' */ qh tracefacet_id= UINT_MAX; /* recompile to trace a facet */ qh tracevertex_id= UINT_MAX; /* recompile to trace a vertex */ - qh_RANDOMseed_(1); -} /* initqhull_start */ + seed= (int)time(&timedata); + qh_RANDOMseed_(seed); + qh run_id= qh_RANDOMint+1; /* disallow 0 [UsingQhullLib::NOqhRunId] */ + 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> @@ -1820,13 +1923,13 @@ void qh_initthresholds(char *command) { while (*s && !isspace(key= *s++)) { if (key == 'd' || key == 'D') { if (!isdigit(*s)) { - fprintf(qh ferr, "qhull warning: no dimension given for Print option '%c' at: %s. Ignored\n", + qh_fprintf(qh ferr, 7044, "qhull warning: no dimension given for Print option '%c' at: %s. Ignored\n", key, s-1); continue; } - index= qh_strtol (s, &s); + index= qh_strtol(s, &s); if (index >= qh hull_dim) { - fprintf(qh ferr, "qhull warning: dimension %d for Print option '%c' is >= %d. Ignored\n", + qh_fprintf(qh ferr, 7045, "qhull warning: dimension %d for Print option '%c' is >= %d. Ignored\n", index, key, qh hull_dim); continue; } @@ -1834,7 +1937,7 @@ void qh_initthresholds(char *command) { s++; value= qh_strtod(s, &s); if (fabs((double)value) > 1.0) { - fprintf(qh ferr, "qhull warning: value %2.4g for Print option %c is > +1 or < -1. Ignored\n", + qh_fprintf(qh ferr, 7046, "qhull warning: value %2.4g for Print option %c is > +1 or < -1. Ignored\n", value, key); continue; } @@ -1859,13 +1962,13 @@ void qh_initthresholds(char *command) { s++; else if (key == 'b' || key == 'B') { if (!isdigit(*s)) { - fprintf(qh ferr, "qhull warning: no dimension given for Qhull option %c. Ignored\n", + qh_fprintf(qh ferr, 7047, "qhull warning: no dimension given for Qhull option %c. Ignored\n", key); continue; } - index= qh_strtol (s, &s); + index= qh_strtol(s, &s); if (index >= maxdim) { - fprintf(qh ferr, "qhull warning: dimension %d for Qhull option %c is >= %d. Ignored\n", + qh_fprintf(qh ferr, 7048, "qhull warning: dimension %d for Qhull option %c is >= %d. Ignored\n", index, key, maxdim); continue; } @@ -1883,13 +1986,13 @@ void qh_initthresholds(char *command) { } } }else { - while (*s && !isspace (*s)) + while (*s && !isspace(*s)) s++; } - while (isspace (*s)) + while (isspace(*s)) s++; } - for (k= qh hull_dim; k--; ) { + for (k=qh hull_dim; k--; ) { if (qh lower_threshold[k] > -REALmax/2) { qh GOODthreshold= True; if (qh upper_threshold[k] < REALmax/2) { @@ -1909,27 +2012,28 @@ void qh_initthresholds(char *command) { 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 (char *option, int *i, realT *r) { +void qh_option(char *option, int *i, realT *r) { char buf[200]; int len, maxlen; - sprintf (buf, " %s", option); + sprintf(buf, " %s", option); if (i) - sprintf (buf+strlen(buf), " %d", *i); + sprintf(buf+strlen(buf), " %d", *i); if (r) - sprintf (buf+strlen(buf), " %2.2g", *r); - len= strlen(buf); + sprintf(buf+strlen(buf), " %2.2g", *r); + len= (int)strlen(buf); /* WARN64 */ qh qhull_optionlen += len; - maxlen= sizeof (qh qhull_options) - len -1; + maxlen= sizeof(qh qhull_options) - len -1; maximize_(maxlen, 0); - if (qh qhull_optionlen >= 80 && maxlen > 0) { + if (qh qhull_optionlen >= qh_OPTIONline && maxlen > 0) { qh qhull_optionlen= len; - strncat (qh qhull_options, "\n", maxlen--); + strncat(qh qhull_options, "\n", maxlen--); } - strncat (qh qhull_options, buf, maxlen); + strncat(qh qhull_options, buf, maxlen); } /* option */ #if qh_QHpointer @@ -1939,7 +2043,7 @@ void qh_option (char *option, int *i, realT *r) { 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 @@ -1949,29 +2053,31 @@ void qh_option (char *option, int *i, realT *r) { is complicated. The procedures will be redesigned. see: - qh_save_qhull() + qh_save_qhull(), UsingQhullLib */ -void qh_restore_qhull (qhT **oldqh) { +void qh_restore_qhull(qhT **oldqh) { - if (*oldqh && strcmp ((*oldqh)->qhull, "qhull")) { - fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n", + 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); + qh_errexit(qh_ERRqhull, NULL, NULL); } if (qh_qh) { - fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not save or free existing qhull\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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) { - fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not previously save qhull %p\n", + 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_errexit(qh_ERRqhull, NULL, NULL); } qh_qh= *oldqh; *oldqh= NULL; qh_qhstat= qh old_qhstat; qhmem.tempstack= qh old_tempstack; - trace1((qh ferr, "qh_restore_qhull: restored qhull from %p\n", *oldqh)); + 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" @@ -1994,13 +2100,13 @@ void qh_restore_qhull (qhT **oldqh) { see: qh_restore_qhull() */ -qhT *qh_save_qhull (void) { +qhT *qh_save_qhull(void) { qhT *oldqh; - trace1((qhmem.ferr, "qh_save_qhull: save qhull %p\n", qh_qh)); + trace1((qhmem.ferr, 1045, "qh_save_qhull: save qhull %p\n", qh_qh)); if (!qh_qh) { - fprintf (qhmem.ferr, "qhull internal error (qh_save_qhull): qhull not initialized\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_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; @@ -2013,29 +2119,3 @@ qhT *qh_save_qhull (void) { #endif -/*-<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); - if (s< (*endp) && (*endp)[-1] == ' ') - (*endp)--; - return result; -} /* strtol */ diff --git a/src/index.htm b/src/index.htm index de1873e..02d546c 100644 --- a/src/index.htm +++ b/src/index.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -35,8 +35,8 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> <blockquote> <p>The following sections provide an overview and index to Qhull's functions, macros, and data structures. Each -section starts with an introduction. Also see <a href=../html/qh-in.htm#library>Calling -Qhull from your program</a>.</p> +section starts with an introduction. Also see <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> @@ -69,10 +69,10 @@ When reading code with an editor, a search for 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="qhull.h">qhull.h</a>. It defines most +<p>A useful starting point is <a href="qhulllib.h">qhulllib.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="qhull.h#qh_PRINT">qh_PRINT...</a> constant. +determine the corresponding <a href="qhulllib.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, @@ -86,7 +86,7 @@ to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>. </p> </blockquote> -<p><b>Copyright © 1997-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1997-2009 The Geometry Center, Minneapolis MN</b></p> <hr> @@ -98,7 +98,7 @@ refer to these files for detailed information.</p> <blockquote> <dl> -<dt><a href="qhull.h"><b>qhull.h</b></a> </dt> +<dt><a href="qhulllib.h"><b>qhulllib.h</b></a> </dt> <dd>Include file for the Qhull library, <tt>qhull.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>. @@ -109,7 +109,9 @@ Other data structures and variables are documented under <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> </dt> +<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 @@ -119,7 +121,7 @@ in <tt>geom.c</tt> while infrequent ones are in <tt>geom2.c</tt>. <dt> </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="qhull.h"><b>qhull.h</b></a> </dt> +<a href="qhulllib.h"><b>qhulllib.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. @@ -153,7 +155,7 @@ rename redundant vertices.</dd> <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="qhull.h"><b>qhull.h</b></a> </dt> +<a href="qhulllib.h"><b>qhulllib.h</b></a> </dt> <dd>Polyhedral routines. Qhull produces a polyhedron as a list of facets with vertices, neighbors, ridges, and geometric information. <tt>Qhull.h</tt> defines the main @@ -162,8 +164,8 @@ while infrequent ones are in <tt>poly2.c</tt>.</dd> <dt> </dt> <dt><a href="qh-qhull.htm#TOC"><b>Qhull</b></a><b>, </b> -<a href="qhull.c"><b>qhull.c</b></a><b>, </b> -<a href="qhull.h"><b>qhull.h</b></a><b>, </b> +<a href="qhulllib.c"><b>qhulllib.c</b></a><b>, </b> +<a href="qhulllib.h"><b>qhulllib.h</b></a><b>, </b> <a href="qhull_a.h"><b>qhull_a.h</b></a><b>, </b> <a href="unix.c"><b>unix.c</b></a> <b>, </b> <a href="qconvex.c"><b>qconvex.c</b></a> <b>, </b> @@ -171,7 +173,7 @@ while infrequent ones are in <tt>poly2.c</tt>.</dd> <a href="qhalf.c"><b>qhalf.c</b></a> <b>, </b> <a href="qvoronoi.c"><b>qvoronoi.c</b></a> </dt> <dd>Top-level routines. The Quickhull algorithm is -implemented by <tt>qhull.c</tt>. <tt>qhull_a.h</tt> +implemented by <tt>qhulllib.c</tt>. <tt>qhull_a.h</tt> includes all header files. </dd> <dt> </dt> @@ -218,7 +220,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/io.c b/src/io.c index 2ef5b94..94910ed 100644 --- a/src/io.c +++ b/src/io.c @@ -1,7 +1,7 @@ /*<html><pre> -<a href="qh-io.htm" >-------------------------------</a><a name="TOP">-</a> - io.c + io.c Input/Output routines of qhull application see qh-io.htm and io.h @@ -13,7 +13,9 @@ 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-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/io.c#29 $$Change: 1095 $ + $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ */ #include "qhull_a.h" @@ -22,9 +24,11 @@ /*-<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 @@ -33,66 +37,63 @@ prints output in qh.PRINTout order */ void qh_produce_output(void) { - int i, tempsize= qh_setsize ((setT*)qhmem.tempstack), d_1; + int tempsize= qh_setsize((setT*)qhmem.tempstack); + + qh_prepare_output(); + qh_produce_output2(); + if (qh_setsize((setT*)qhmem.tempstack) != tempsize) { + qh_fprintf(qh ferr, 6206, "qhull internal error (qh_produce_output): temporary sets not empty(%d)\n", + qh_setsize((setT*)qhmem.tempstack)); + qh_errexit(qh_ERRqhull, NULL, NULL); + } +} /* produce_output */ + + +void qh_produce_output2(void) { + int i, tempsize= qh_setsize((setT*)qhmem.tempstack), d_1; - if (qh VORONOI) { - qh_clearcenters (qh_ASvoronoi); - qh_vertexneighbors(); - } - if (qh TRIangulate) { - qh_triangulate(); - if (qh VERIFYoutput && !qh CHECKfrequently) - qh_checkpolygon (qh facet_list); - } - qh_findgood_all (qh facet_list); - if (qh GETarea) - qh_getarea(qh facet_list); - if (qh KEEParea || qh KEEPmerge || qh KEEPminArea < REALmax/2) - qh_markkeep (qh facet_list); if (qh PRINTsummary) qh_printsummary(qh ferr); else if (qh PRINTout[0] == qh_PRINTnone) qh_printsummary(qh fout); - for (i= 0; i < qh_PRINTEND; i++) - qh_printfacets (qh fout, qh PRINTout[i], qh facet_list, NULL, !qh_ALL); + 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); + qh_printstats(qh ferr, qhstat precision, NULL); + if (qh VERIFYoutput && (zzval_(Zridge) > 0 || zzval_(Zridgemid) > 0)) + qh_printstats(qh ferr, qhstat vridges, NULL); if (qh PRINTstatistics) { - qh_collectstatistics(); qh_printstatistics(qh ferr, ""); - qh_memstatistics (qh ferr); + qh_memstatistics(qh ferr); d_1= sizeof(setT) + (qh hull_dim - 1) * SETelemsize; - fprintf(qh ferr, "\ + 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", - sizeof(mergeT), sizeof(ridgeT), - sizeof(vertexT), sizeof(facetT), - qh normal_size, d_1, d_1 + SETelemsize); + sizeof(mergeT), sizeof(ridgeT), + sizeof(vertexT), sizeof(facetT), + qh normal_size, d_1, d_1 + SETelemsize); } - if (qh_setsize ((setT*)qhmem.tempstack) != tempsize) { - fprintf (qh ferr, "qhull internal error (qh_produce_output): temporary sets not empty (%d)\n", - qh_setsize ((setT*)qhmem.tempstack)); - qh_errexit (qh_ERRqhull, NULL, NULL); + if (qh_setsize((setT*)qhmem.tempstack) != tempsize) { + qh_fprintf(qh ferr, 6065, "qhull internal error (qh_produce_output2): temporary sets not empty(%d)\n", + qh_setsize((setT*)qhmem.tempstack)); + qh_errexit(qh_ERRqhull, NULL, NULL); } -} /* produce_output */ - +} /* produce_output2 */ /*-<a href="qh-io.htm#TOC" >-------------------------------</a><a name="dfacet">-</a> - + dfacet( id ) print facet by id, for debugging */ -void dfacet (unsigned id) { +void dfacet(unsigned id) { facetT *facet; FORALLfacets { if (facet->id == id) { - qh_printfacet (qh fout, facet); + qh_printfacet(qh fout, facet); break; } } @@ -101,16 +102,16 @@ void dfacet (unsigned id) { /*-<a href="qh-io.htm#TOC" >-------------------------------</a><a name="dvertex">-</a> - + dvertex( id ) print vertex by id, for debugging */ -void dvertex (unsigned id) { +void dvertex(unsigned id) { vertexT *vertex; FORALLvertices { if (vertex->id == id) { - qh_printvertex (qh fout, vertex); + qh_printvertex(qh fout, vertex); break; } } @@ -119,19 +120,19 @@ void dvertex (unsigned id) { /*-<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 + used by qsort() to order vertices by point id */ int qh_compare_vertexpoint(const void *p1, const void *p2) { vertexT *a= *((vertexT **)p1), *b= *((vertexT **)p2); - - return ((qh_pointid(a->point) > qh_pointid(b->point)?1:-1)); + + return((qh_pointid(a->point) > qh_pointid(b->point)?1:-1)); } /* compare_vertexpoint */ /*-<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 */ @@ -141,7 +142,7 @@ int qh_compare_facetarea(const void *p1, const void *p2) { if (!a->isarea) return -1; if (!b->isarea) - return 1; + return 1; if (a->f.area > b->f.area) return 1; else if (a->f.area == b->f.area) @@ -151,19 +152,19 @@ int qh_compare_facetarea(const void *p1, const void *p2) { /*-<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) { facetT *a= *((facetT **)p1), *b= *((facetT **)p2); - - return (a->nummerge - b->nummerge); + + 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 */ @@ -172,16 +173,49 @@ int qh_compare_facetvisit(const void *p1, const void *p2) { int i,j; if (!(i= a->visitid)) - i= - a->id; /* do not convert to int */ + i= 0 - a->id; /* do not convert to int, sign distinguishes id from visitid */ if (!(j= b->visitid)) - j= - b->id; - return (i - j); + j= 0 - b->id; + return(i - j); } /* compare_facetvisit */ +/*-<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, 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, + + qh_countfacets( facetlist, facets, printall, numfacets, numsimplicial, totneighbors, numridges, numcoplanar, numtricoplanars ) count good facets for printing and set visitid if allfacets, ignores qh_skipfacet() @@ -193,10 +227,10 @@ int qh_compare_facetvisit(const void *p1, const void *p2) { 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, + if qh.NEWfacets, does not count visible facets (matches qh_printafacet) design: @@ -205,7 +239,7 @@ int qh_compare_facetvisit(const void *p1, const void *p2) { mark facet->visitid update counts */ -void qh_countfacets (facetT *facetlist, setT *facets, boolT printall, +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; @@ -216,32 +250,33 @@ void qh_countfacets (facetT *facetlist, setT *facets, boolT printall, facet->visitid= 0; else { facet->visitid= ++numfacets; - totneighbors += qh_setsize (facet->neighbors); + totneighbors += qh_setsize(facet->neighbors); if (facet->simplicial) { numsimplicial++; - if (facet->keepcentrum && facet->tricoplanar) - numtricoplanars++; + if (facet->keepcentrum && facet->tricoplanar) + numtricoplanars++; }else - numridges += qh_setsize (facet->ridges); + numridges += qh_setsize(facet->ridges); if (facet->coplanarset) - numcoplanars += qh_setsize (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); + totneighbors += qh_setsize(facet->neighbors); if (facet->simplicial){ numsimplicial++; - if (facet->keepcentrum && facet->tricoplanar) - numtricoplanars++; + if (facet->keepcentrum && facet->tricoplanar) + numtricoplanars++; }else - numridges += qh_setsize (facet->ridges); + numridges += qh_setsize(facet->ridges); if (facet->coplanarset) - numcoplanars += qh_setsize (facet->coplanarset); + numcoplanars += qh_setsize(facet->coplanarset); } } qh visit_id += numfacets+1; @@ -255,15 +290,15 @@ void qh_countfacets (facetT *facetlist, setT *facets, boolT printall, /*-<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 @@ -273,13 +308,13 @@ void qh_countfacets (facetT *facetlist, setT *facets, boolT printall, 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 @@ -294,13 +329,13 @@ void qh_countfacets (facetT *facetlist, setT *facets, boolT printall, 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) { +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); + setT *points= qh_settemp(qh TEMPsize); boolT nearzero= False; boolT unbounded= False; int numcenters= 0; @@ -308,7 +343,7 @@ pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *of 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++) + for (k=0; k < dim; k++) midpoint[k]= (vertex->point[k] + vertexA->point[k])/2; FOREACHfacet_(centers) { numcenters++; @@ -316,81 +351,81 @@ pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *of unbounded= True; else { if (!facet->center) - facet->center= qh_facetcenter (facet->vertices); - qh_setappend (&points, 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); + 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); + 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; + qh_setappend(&points, midpoint); + simplex= points; }else { - fprintf(qh ferr, "qh_detvnorm: too few points (%d) to compute separating plane\n", numcenters); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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", + 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--; ) + 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); + 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); + dist= qh_distnorm(dim, inpoint, normal, &offset); if (dist > 0) { offset= -offset; normalp= normal; - for (k= dim; k--; ) { + for (k=dim; k--; ) { *normalp= -(*normalp); normalp++; } } if (qh VERIFYoutput || qh PRINTstatistics) { - pointid= qh_pointid (vertex->point); - pointidA= qh_pointid (vertexA->point); + pointid= qh_pointid(vertex->point); + pointidA= qh_pointid(vertexA->point); if (!unbounded) { zinc_(Zdiststat); - dist= qh_distnorm (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 ferr, "qh_detvnorm: points %d %d midpoint dist %2.2g\n", + trace4((qh ferr, 4014, "qh_detvnorm: points %d %d midpoint dist %2.2g\n", pointid, pointidA, dist)); - for (k= 0; k < dim; k++) + 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 */ + 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; + angle= angle + 1.0; else - angle= angle - 1.0; + angle= angle - 1.0; if (angle < 0.0) - angle -= angle; - trace4((qh ferr, "qh_detvnorm: points %d %d angle %2.2g nearzero %d\n", + 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); @@ -404,16 +439,16 @@ pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *of } if (simplex != points) { FOREACHpoint_i_(points) { - if (!qh_setin (simplex, point)) { + if (!qh_setin(simplex, point)) { facet= SETelemt_(centers, point_i, facetT); - zinc_(Zdiststat); - dist= qh_distnorm (dim, point, normal, &offset); + zinc_(Zdiststat); + dist= qh_distnorm(dim, point, normal, &offset); if (dist < 0) dist= -dist; - zzinc_(Zridge); + zzinc_(Zridge); wwmax_(Wridgemax, dist); wwadd_(Wridge, dist); - trace4((qh ferr, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n", + trace4((qh ferr, 4016, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n", pointid, pointidA, facet->visitid, dist)); } } @@ -421,8 +456,8 @@ pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *of } *offsetp= offset; if (simplex != points) - qh_settempfree (&simplex); - qh_settempfree (&points); + qh_settempfree(&simplex); + qh_settempfree(&points); return normal; } /* detvnorm */ @@ -437,28 +472,28 @@ pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *of 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); +setT *qh_detvridge(vertexT *vertex) { + setT *centers= qh_settemp(qh TEMPsize); + setT *tricenters= qh_settemp(qh TEMPsize); facetT *neighbor, **neighborp; boolT firstinf= True; - + FOREACHneighbor_(vertex) { if (neighbor->seen) { if (neighbor->visitid) { - if (!neighbor->tricoplanar || qh_setunique (&tricenters, neighbor->center)) - qh_setappend (¢ers, neighbor); + if (!neighbor->tricoplanar || qh_setunique(&tricenters, neighbor->center)) + qh_setappend(¢ers, neighbor); }else if (firstinf) { firstinf= False; - qh_setappend (¢ers, neighbor); + qh_setappend(¢ers, neighbor); } } } - qsort (SETaddr_(centers, facetT), qh_setsize (centers), - sizeof (facetT *), qh_compare_facetvisit); - qh_settempfree (&tricenters); + qsort(SETaddr_(centers, facetT), qh_setsize(centers), + sizeof(facetT *), qh_compare_facetvisit); + qh_settempfree(&tricenters); return centers; -} /* detvridge */ +} /* detvridge */ /*-<a href="qh-io.htm#TOC" >-------------------------------</a><a name="detvridge3">-</a> @@ -470,7 +505,7 @@ setT *qh_detvridge (vertexT *vertex) { returns: temporary set of centers (facets, i.e., Voronoi vertices) - listed in adjacency order (not oriented) + listed in adjacency order (!oriented) all facet->seen2= True design: @@ -480,11 +515,11 @@ setT *qh_detvridge (vertexT *vertex) { 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); + 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) { @@ -493,23 +528,23 @@ setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex) { break; } } - while (facet) { + while (facet) { facet->seen2= True; if (neighbor->seen) { if (facet->visitid) { - if (!facet->tricoplanar || qh_setunique (&tricenters, facet->center)) - qh_setappend (¢ers, facet); + if (!facet->tricoplanar || qh_setunique(&tricenters, facet->center)) + qh_setappend(¢ers, facet); }else if (firstinf) { firstinf= False; - qh_setappend (¢ers, facet); + qh_setappend(¢ers, facet); } } FOREACHneighbor_(facet) { if (!neighbor->seen2) { - if (qh_setin (vertex->neighbors, neighbor)) + if (qh_setin(vertex->neighbors, neighbor)) break; - else - neighbor->seen2= True; + else + neighbor->seen2= True; } } facet= neighbor; @@ -517,21 +552,21 @@ setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex) { if (qh CHECKfrequently) { FOREACHneighbor_(vertex) { if (!neighbor->seen2) { - fprintf (stderr, "qh_detvridge3: neigbors of vertex p%d are not connected at facet %d\n", - qh_pointid (vertex->point), neighbor->id); - qh_errexit (qh_ERRqhull, neighbor, NULL); + 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) + FOREACHneighbor_(atvertex) neighbor->seen2= True; - qh_settempfree (&tricenters); + qh_settempfree(&tricenters); return centers; -} /* detvridge3 */ +} /* 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) @@ -542,19 +577,19 @@ setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex) { all facet->seen= False all facet->seen2= True (for qh_detvridge3) all facet->visitid == 0 if vertex_at_infinity - == index of Voronoi vertex + == index of Voronoi vertex >= qh.num_facets if ignored innerouter: - qh_RIDGEall-- both inner (bounded) and outer (unbounded) ridges + 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*) @@ -564,26 +599,26 @@ setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex) { 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 + 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) { +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); + setT *tricenters= qh_settemp(qh TEMPsize); vertexT *vertex, **vertexp; boolT firstinf; @@ -593,31 +628,31 @@ int qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT qh vertex_visit++; atvertex->seen= True; if (visitall) { - FORALLvertices + FORALLvertices vertex->seen= False; } FOREACHneighbor_(atvertex) { - if (neighbor->visitid < numfacets) + 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; + vertex->visitid= qh vertex_visit; count= 0; firstinf= True; - qh_settruncate (tricenters, 0); + qh_settruncate(tricenters, 0); FOREACHneighborA_(vertex) { if (neighborA->seen) { - if (neighborA->visitid) { - if (!neighborA->tricoplanar || qh_setunique (&tricenters, neighborA->center)) - count++; + 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) { @@ -630,63 +665,63 @@ int qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT unbounded= True; } totridges++; - trace4((qh ferr, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n", - count, qh_pointid (atvertex->point), qh_pointid (vertex->point))); - if (printvridge) { - if (inorder && qh hull_dim == 3+1) /* 3-d Voronoi diagram */ + 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) { + if (inorder && qh hull_dim == 3+1) /* 3-d Voronoi diagram */ centers= qh_detvridge3 (atvertex, vertex); - else - centers= qh_detvridge (vertex); + else + centers= qh_detvridge(vertex); (*printvridge) (fp, atvertex, vertex, centers, unbounded); - qh_settempfree (¢ers); + qh_settempfree(¢ers); } } } } } } - FOREACHneighbor_(atvertex) + FOREACHneighbor_(atvertex) neighbor->seen= False; - qh_settempfree (&tricenters); + 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 + 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= 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) { +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_clearcenters(qh_ASvoronoi); qh_vertexneighbors(); maximize_(qh visit_id, (unsigned) qh num_facets); FORALLfacets { @@ -698,20 +733,20 @@ int qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RI if (facet->upperdelaunay == isupper) facet->visitid= numcenters++; } - FORALLvertices + FORALLvertices vertex->seen= False; FORALLvertices { if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex) continue; - totridges += qh_eachvoronoi (fp, printvridge, vertex, + 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 @@ -723,7 +758,7 @@ int qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RI 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); @@ -736,21 +771,21 @@ void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mind *mindist= dist; *point0= qh_projectpoint(vertex0->point, facet, dist); qh_distplane(vertex1->point, facet, &dist); - minimize_(*mindist, 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 @@ -761,38 +796,38 @@ void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mind for each selected facet in facets or facetlist append unvisited vertices to vertex set */ -setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets) { +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); + vertices= qh_settemp(qh num_vertices); FORALLvertices { - vertex->visitid= qh vertex_visit; - qh_setappend (&vertices, vertex); + vertex->visitid= qh vertex_visit; + qh_setappend(&vertices, vertex); } }else { - vertices= qh_settemp (qh TEMPsize); + vertices= qh_settemp(qh TEMPsize); FORALLfacet_(facetlist) { - if (!allfacets && qh_skipfacet (facet)) + if (!allfacets && qh_skipfacet(facet)) continue; FOREACHvertex_(facet->vertices) { if (vertex->visitid != qh vertex_visit) { vertex->visitid= qh vertex_visit; - qh_setappend (&vertices, vertex); + qh_setappend(&vertices, vertex); } } } } FOREACHfacet_(facets) { - if (!allfacets && qh_skipfacet (facet)) + if (!allfacets && qh_skipfacet(facet)) continue; FOREACHvertex_(facet->vertices) { if (vertex->visitid != qh vertex_visit) { vertex->visitid= qh vertex_visit; - qh_setappend (&vertices, vertex); + qh_setappend(&vertices, vertex); } } } @@ -801,39 +836,39 @@ setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets) { /*-<a href="qh-geom.htm#TOC" >-------------------------------</a><a name="geomplanes">-</a> - + qh_geomplanes( facet, outerplane, innerplane ) - return outer and inner planes for Geomview + 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) { +void qh_geomplanes(facetT *facet, realT *outerplane, realT *innerplane) { realT radius; if (qh MERGING || qh JOGGLEmax < REALmax/2) { - qh_outerinner (facet, outerplane, innerplane); + qh_outerinner(facet, outerplane, innerplane); radius= qh PRINTradius; if (qh JOGGLEmax < REALmax/2) - radius -= qh JOGGLEmax * sqrt (qh hull_dim); /* already accounted for in qh_outerinner() */ + 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 + }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 (not part of convex hull) + ignores visible facets (!part of convex hull) returns: may clear facet->good @@ -849,23 +884,23 @@ void qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane) { clear facet->good for all but n most merged facets if qh.KEEPminarea clear facet->good if area too small - update qh.num_good + update qh.num_good */ -void qh_markkeep (facetT *facetlist) { +void qh_markkeep(facetT *facetlist) { facetT *facet, **facetp; - setT *facets= qh_settemp (qh num_facets); + setT *facets= qh_settemp(qh num_facets); int size, count; - trace2((qh ferr, "qh_markkeep: only keep %d largest and/or %d most merged facets and/or min area %.2g\n", + 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); + qh_setappend(&facets, facet); } - size= qh_setsize (facets); + size= qh_setsize(facets); if (qh KEEParea) { - qsort (SETaddr_(facets, facetT), size, - sizeof (facetT *), qh_compare_facetarea); + qsort(SETaddr_(facets, facetT), size, + sizeof(facetT *), qh_compare_facetarea); if ((count= size - qh KEEParea) > 0) { FOREACHfacet_(facets) { facet->good= False; @@ -875,8 +910,8 @@ void qh_markkeep (facetT *facetlist) { } } if (qh KEEPmerge) { - qsort (SETaddr_(facets, facetT), size, - sizeof (facetT *), qh_compare_facetmerge); + qsort(SETaddr_(facets, facetT), size, + sizeof(facetT *), qh_compare_facetmerge); if ((count= size - qh KEEPmerge) > 0) { FOREACHfacet_(facets) { facet->good= False; @@ -888,10 +923,10 @@ void qh_markkeep (facetT *facetlist) { if (qh KEEPminArea < REALmax/2) { FOREACHfacet_(facets) { if (!facet->isarea || facet->f.area < qh KEEPminArea) - facet->good= False; + facet->good= False; } } - qh_settempfree (&facets); + qh_settempfree(&facets); count= 0; FORALLfacet_(facetlist) { if (facet->good) @@ -903,54 +938,54 @@ void qh_markkeep (facetT *facetlist) { /*-<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) { +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_clearcenters(qh_ASvoronoi); /* in case, qh_printvdiagram2 called by user */ qh_vertexneighbors(); vertices= qh_pointvertex(); - if (qh ATinfinity) + 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)) { + FORALLfacet_(facetlist) { + if (printall || !qh_skipfacet(facet)) { if (!facet->upperdelaunay) { islower= True; - break; + break; } } } FOREACHfacet_(facets) { - if (printall || !qh_skipfacet (facet)) { + if (printall || !qh_skipfacet(facet)) { if (!facet->upperdelaunay) { islower= True; - break; + break; } } } @@ -964,22 +999,22 @@ setT *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *is } numcenters++; /* qh_INFINITE */ FORALLfacet_(facetlist) { - if (printall || !qh_skipfacet (facet)) + if (printall || !qh_skipfacet(facet)) facet->visitid= numcenters++; } FOREACHfacet_(facets) { - if (printall || !qh_skipfacet (facet)) - facet->visitid= numcenters++; + if (printall || !qh_skipfacet(facet)) + facet->visitid= numcenters++; } *islowerp= islower; *numcentersp= numcenters; - trace2((qh ferr, "qh_markvoronoi: islower %d numcenters %d\n", islower, 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 @@ -996,33 +1031,63 @@ void qh_order_vertexneighbors(vertexT *vertex) { setT *newset; facetT *facet, *neighbor, **neighborp; - trace4((qh ferr, "qh_order_vertexneighbors: order neighbors of v%d for 3-d\n", vertex->id)); - newset= qh_settemp (qh_setsize (vertex->neighbors)); - facet= (facetT*)qh_setdellast (vertex->neighbors); - qh_setappend (&newset, facet); - while (qh_setsize (vertex->neighbors)) { + 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)) { + if (qh_setin(facet->neighbors, neighbor)) { qh_setdel(vertex->neighbors, neighbor); - qh_setappend (&newset, neighbor); + qh_setappend(&newset, neighbor); facet= neighbor; break; } } if (!neighbor) { - fprintf (qh ferr, "qhull internal error (qh_order_vertexneighbors): no neighbor of v%d for f%d\n", + 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_errexit(qh_ERRqhull, facet, NULL); } } - qh_setfree (&vertex->neighbors); - qh_settemppop (); + 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) @@ -1051,7 +1116,7 @@ void qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall) { vertexT *vertex, **vertexp; facetT *neighbor, **neighborp; - if (!printall && qh_skipfacet (facet)) + if (!printall && qh_skipfacet(facet)) return; if (facet->visible && qh NEWfacets && format != qh_PRINTfacets) return; @@ -1059,30 +1124,30 @@ void qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall) { switch (format) { case qh_PRINTarea: if (facet->isarea) { - fprintf (fp, qh_REAL_1, facet->f.area); - fprintf (fp, "\n"); + qh_fprintf(fp, 9009, qh_REAL_1, facet->f.area); + qh_fprintf(fp, 9010, "\n"); }else - fprintf (fp, "0\n"); + qh_fprintf(fp, 9011, "0\n"); break; case qh_PRINTcoplanars: - fprintf (fp, "%d", qh_setsize (facet->coplanarset)); + qh_fprintf(fp, 9012, "%d", qh_setsize(facet->coplanarset)); FOREACHpoint_(facet->coplanarset) - fprintf (fp, " %d", qh_pointid (point)); - fprintf (fp, "\n"); + qh_fprintf(fp, 9013, " %d", qh_pointid(point)); + qh_fprintf(fp, 9014, "\n"); break; case qh_PRINTcentrums: - qh_printcenter (fp, format, NULL, facet); + qh_printcenter(fp, format, NULL, facet); break; case qh_PRINTfacets: - qh_printfacet (fp, facet); + qh_printfacet(fp, facet); break; case qh_PRINTfacets_xridge: - qh_printfacetheader (fp, facet); + 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--; ) { + 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); @@ -1091,153 +1156,153 @@ void qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall) { if (qh PRINTdim != qh hull_dim) qh_normalize2 (color, 3, True, NULL, NULL); if (qh hull_dim <= 2) - qh_printfacet2geom (fp, facet, color); + qh_printfacet2geom(fp, facet, color); else if (qh hull_dim == 3) { if (facet->simplicial) - qh_printfacet3geom_simplicial (fp, facet, color); + qh_printfacet3geom_simplicial(fp, facet, color); else - qh_printfacet3geom_nonsimplicial (fp, facet, color); + qh_printfacet3geom_nonsimplicial(fp, facet, color); }else { if (facet->simplicial) - qh_printfacet4geom_simplicial (fp, facet, color); + qh_printfacet4geom_simplicial(fp, facet, color); else - qh_printfacet4geom_nonsimplicial (fp, facet, color); + qh_printfacet4geom_nonsimplicial(fp, facet, color); } break; case qh_PRINTids: - fprintf (fp, "%d\n", facet->id); + 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); + 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); + qh_printfacetNvertex_simplicial(fp, facet, format); else - qh_printfacetNvertex_nonsimplicial (fp, facet, qh printoutvar++, format); + qh_printfacetNvertex_nonsimplicial(fp, facet, qh printoutvar++, format); break; case qh_PRINTinner: - qh_outerinner (facet, NULL, &innerplane); + qh_outerinner(facet, NULL, &innerplane); offset= facet->offset - innerplane; goto LABELprintnorm; break; /* prevent warning */ case qh_PRINTmerges: - fprintf (fp, "%d\n", facet->nummerge); + 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); + qh_outerinner(facet, &outerplane, NULL); offset= facet->offset - outerplane; LABELprintnorm: if (!facet->normal) { - fprintf (fp, "no normal for facet f%d\n", facet->id); + qh_fprintf(fp, 9017, "no normal for facet f%d\n", facet->id); break; } if (qh CDDoutput) { - fprintf (fp, qh_REAL_1, -offset); - for (k=0; k < qh hull_dim; k++) - fprintf (fp, qh_REAL_1, -facet->normal[k]); + 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++) - fprintf (fp, qh_REAL_1, facet->normal[k]); - fprintf (fp, qh_REAL_1, offset); + 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); } - fprintf (fp, "\n"); + 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++); + qh_printfacet2math(fp, facet, format, qh printoutvar++); + else + qh_printfacet3math(fp, facet, format, qh printoutvar++); break; case qh_PRINTneighbors: - fprintf (fp, "%d", qh_setsize (facet->neighbors)); + qh_fprintf(fp, 9023, "%d", qh_setsize(facet->neighbors)); FOREACHneighbor_(facet) - fprintf (fp, " %d", - neighbor->visitid ? neighbor->visitid - 1: - neighbor->id); - fprintf (fp, "\n"); + 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) { - fprintf (fp, "qhull input error (qh_printafacet): option 'Fp' needs qh feasible_point\n"); + 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); + 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--; ) + 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++); + 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); + qh_memfree(point, qh normal_size); goto LABELprintinfinite; } } } - qh_printpoint (fp, NULL, point); - qh_memfree (point, qh normal_size); + qh_printpoint(fp, NULL, point); + qh_memfree(point, qh normal_size); break; LABELprintinfinite: - for (k= qh hull_dim; k--; ) - fprintf (fp, qh_REAL_1, qh_INFINITE); - fprintf (fp, "\n"); + 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); - fprintf (fp, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist); + 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) - fprintf (fp, "1 "); - qh_printcenter (fp, format, NULL, facet); + qh_fprintf(fp, 9029, "1 "); + qh_printcenter(fp, format, NULL, facet); break; case qh_PRINTvertices: - fprintf (fp, "%d", qh_setsize (facet->vertices)); + qh_fprintf(fp, 9030, "%d", qh_setsize(facet->vertices)); FOREACHvertex_(facet->vertices) - fprintf (fp, " %d", qh_pointid (vertex->point)); - fprintf (fp, "\n"); + qh_fprintf(fp, 9031, " %d", qh_pointid(vertex->point)); + qh_fprintf(fp, 9032, "\n"); 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, int format, facetT *facetlist, setT *facets, boolT printall) { +void qh_printbegin(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) { int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars; int i, num; facetT *facet, **facetp; @@ -1246,98 +1311,101 @@ void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT pointT *point, **pointp, *pointtemp; qh printoutnum= 0; - qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, + qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial, &totneighbors, &numridges, &numcoplanars, &numtricoplanars); switch (format) { case qh_PRINTnone: break; case qh_PRINTarea: - fprintf (fp, "%d\n", numfacets); + qh_fprintf(fp, 9033, "%d\n", numfacets); break; case qh_PRINTcoplanars: - fprintf (fp, "%d\n", numfacets); + qh_fprintf(fp, 9034, "%d\n", numfacets); break; case qh_PRINTcentrums: if (qh CENTERtype == qh_ASnone) - qh_clearcenters (qh_AScentrum); - fprintf (fp, "%d\n%d\n", qh hull_dim, numfacets); + 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); + qh_printvertexlist(fp, "Vertices and facets:\n", facetlist, facets, printall); break; - case qh_PRINTgeom: + case qh_PRINTgeom: if (qh hull_dim > 4) /* qh_initqhull_globals also checks */ goto LABELnoformat; if (qh VORONOI && qh hull_dim > 3) /* PRINTdim == DROPdim == hull_dim-1 */ goto LABELnoformat; if (qh hull_dim == 2 && (qh PRINTridges || qh DOintersections)) - fprintf (qh ferr, "qhull warning: output for ridges and intersections not implemented in 2-d\n"); + 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))) - fprintf (qh ferr, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n"); + (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)) - fprintf (qh ferr, "qhull warning: output for vertices not implemented in 4-d\n"); + qh_fprintf(qh ferr, 7051, "qhull warning: output for vertices not implemented in 4-d\n"); if (qh PRINTdim == 4 && qh DOintersections && qh PRINTnoplanes) - fprintf (qh ferr, "qhull warning: 'Gnh' generates no output in 4-d\n"); + qh_fprintf(qh ferr, 7052, "qhull warning: 'Gnh' generates no output in 4-d\n"); if (qh PRINTdim == 2) { - fprintf(fp, "{appearance {linewidth 3} LIST # %s | %s\n", - qh rbox_command, qh qhull_command); + qh_fprintf(fp, 9036, "{appearance {linewidth 3} LIST # %s | %s\n", + qh rbox_command, qh qhull_command); }else if (qh PRINTdim == 3) { - fprintf(fp, "{appearance {+edge -evert linewidth 2} LIST # %s | %s\n", - qh rbox_command, qh qhull_command); + 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); + qh_printend4geom(NULL, facet, &num, printall); FOREACHfacet_(facets) - qh_printend4geom (NULL, facet, &num, printall); + qh_printend4geom(NULL, facet, &num, printall); qh ridgeoutnum= num; qh printoutvar= 0; /* counts number of ridges in output */ - fprintf (fp, "LIST # %s | %s\n", qh rbox_command, qh qhull_command); + 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); + num= qh num_points + qh_setsize(qh other_points); if (qh DELAUNAY && qh ATinfinity) - num--; + num--; if (qh PRINTdim == 4) - fprintf (fp, "4VECT %d %d 1\n", num, num); + qh_fprintf(fp, 9039, "4VECT %d %d 1\n", num, num); else - fprintf (fp, "VECT %d %d 1\n", num, num); - for (i= num; i--; ) { + qh_fprintf(fp, 9040, "VECT %d %d 1\n", num, num); + + for (i=num; i--; ) { if (i % 20 == 0) - fprintf (fp, "\n"); - fprintf (fp, "1 "); + qh_fprintf(fp, 9041, "\n"); + qh_fprintf(fp, 9042, "1 "); } - fprintf (fp, "# 1 point per line\n1 "); - for (i= num-1; i--; ) { + qh_fprintf(fp, 9043, "# 1 point per line\n1 "); + for (i=num-1; i--; ) { if (i % 20 == 0) - fprintf (fp, "\n"); - fprintf (fp, "0 "); + qh_fprintf(fp, 9044, "\n"); + qh_fprintf(fp, 9045, "0 "); } - fprintf (fp, "# 1 color for all\n"); + 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); - } + 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); + if (qh PRINTdim == 4) + qh_printpoint(fp, NULL, point); + else + qh_printpoint3 (fp, point); } - fprintf (fp, "0 1 1 1 # color of points\n"); + 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 */ - fprintf(fp, "4OFF %d %d 1\n", 3*qh ridgeoutnum, qh ridgeoutnum); + 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); @@ -1351,98 +1419,97 @@ void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT }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); + maximize_(qh PRINTradius, qh MINvisible); if (qh JOGGLEmax < REALmax/2) - qh PRINTradius += qh JOGGLEmax * sqrt (qh hull_dim); + 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); + (qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) { + vertices= qh_facetvertices(facetlist, facets, printall); if (qh PRINTspheres && qh PRINTdim <= 3) - qh_printspheres (fp, vertices, qh PRINTradius); + 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); - } + 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 (!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; + 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 (!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; + 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_settempfree(&vertices); } qh visit_id++; /* for printing hyperplane intersections */ break; case qh_PRINTids: - fprintf (fp, "%d\n", numfacets); + qh_fprintf(fp, 9049, "%d\n", numfacets); break; case qh_PRINTincidences: if (qh VORONOI && qh PRINTprecision) - fprintf (qh ferr, "qhull warning: writing Delaunay. Use 'p' or 'o' for Voronoi centers\n"); + qh_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) - fprintf(fp, "%d\n", numfacets); + qh_fprintf(fp, 9050, "%d\n", numfacets); else - fprintf(fp, "%d\n", numsimplicial+numridges); + qh_fprintf(fp, 9051, "%d\n", numsimplicial+numridges); break; case qh_PRINTinner: case qh_PRINTnormals: case qh_PRINTouter: if (qh CDDoutput) - fprintf (fp, "%s | %s\nbegin\n %d %d real\n", qh rbox_command, - qh qhull_command, numfacets, qh hull_dim+1); + qh_fprintf(fp, 9052, "%s | %s\nbegin\n %d %d real\n", qh rbox_command, + qh qhull_command, numfacets, qh hull_dim+1); else - fprintf (fp, "%d\n%d\n", qh hull_dim+1, numfacets); + qh_fprintf(fp, 9053, "%d\n%d\n", qh hull_dim+1, numfacets); break; - case qh_PRINTmathematica: + case qh_PRINTmathematica: case qh_PRINTmaple: if (qh hull_dim > 3) /* qh_initbuffers also checks */ goto LABELnoformat; if (qh VORONOI) - fprintf (qh ferr, "qhull warning: output is the Delaunay triangulation\n"); + qh_fprintf(qh ferr, 7054, "qhull warning: output is the Delaunay triangulation\n"); if (format == qh_PRINTmaple) { if (qh hull_dim == 2) - fprintf(fp, "PLOT(CURVES(\n"); + qh_fprintf(fp, 9054, "PLOT(CURVES(\n"); else - fprintf(fp, "PLOT3D(POLYGONS(\n"); + qh_fprintf(fp, 9055, "PLOT3D(POLYGONS(\n"); }else - fprintf(fp, "{\n"); + qh_fprintf(fp, 9056, "{\n"); qh printoutvar= 0; /* counts number of facets for notfirst */ break; case qh_PRINTmerges: - fprintf (fp, "%d\n", numfacets); + qh_fprintf(fp, 9057, "%d\n", numfacets); break; case qh_PRINTpointintersect: - fprintf (fp, "%d\n%d\n", qh hull_dim, numfacets); + qh_fprintf(fp, 9058, "%d\n%d\n", qh hull_dim, numfacets); break; case qh_PRINTneighbors: - fprintf (fp, "%d\n", numfacets); + qh_fprintf(fp, 9059, "%d\n", numfacets); break; case qh_PRINToff: case qh_PRINTtriangles: @@ -1450,53 +1517,53 @@ void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT goto LABELnoformat; num = qh hull_dim; if (format == qh_PRINToff || qh hull_dim == 2) - fprintf (fp, "%d\n%d %d %d\n", num, - qh num_points+qh_setsize (qh other_points), numfacets, totneighbors/2); + 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 */ + qh printoutvar= qh num_points+qh_setsize(qh other_points); /* first centrum */ if (qh DELAUNAY) num--; /* drop last dimension */ - fprintf (fp, "%d\n%d %d %d\n", num, qh printoutvar - + numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2); + 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, -1); FOREACHpoint_(qh other_points) - qh_printpointid (qh fout, NULL, num, point, -1); + qh_printpointid(qh fout, NULL, num, point, -1); if (format == qh_PRINTtriangles && qh hull_dim > 2) { FORALLfacets { - if (!facet->simplicial && facet->visitid) - qh_printcenter (qh fout, format, NULL, facet); + if (!facet->simplicial && facet->visitid) + qh_printcenter(qh fout, format, NULL, facet); } } break; case qh_PRINTpointnearest: - fprintf (fp, "%d\n", numcoplanars); + qh_fprintf(fp, 9062, "%d\n", numcoplanars); break; case qh_PRINTpoints: if (!qh VORONOI) goto LABELnoformat; if (qh CDDoutput) - fprintf (fp, "%s | %s\nbegin\n%d %d real\n", qh rbox_command, - qh qhull_command, numfacets, qh hull_dim); + qh_fprintf(fp, 9063, "%s | %s\nbegin\n%d %d real\n", qh rbox_command, + qh qhull_command, numfacets, qh hull_dim); else - fprintf (fp, "%d\n%d\n", qh hull_dim-1, numfacets); + qh_fprintf(fp, 9064, "%d\n%d\n", qh hull_dim-1, numfacets); break; case qh_PRINTvertices: - fprintf (fp, "%d\n", numfacets); + qh_fprintf(fp, 9065, "%d\n", numfacets); break; case qh_PRINTsummary: default: LABELnoformat: - fprintf (qh ferr, "qhull internal error (qh_printbegin): can not use this format for dimension %d\n", + qh_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); + 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. @@ -1507,43 +1574,44 @@ void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT 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, int format, char *string, facetT *facet) { +void qh_printcenter(FILE *fp, int format, char *string, facetT *facet) { int k, num; if (qh CENTERtype != qh_ASvoronoi && qh CENTERtype != qh_AScentrum) return; if (string) - fprintf (fp, string, facet->id); + 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); + facet->center= qh_facetcenter(facet->vertices); for (k=0; k < num; k++) - fprintf (fp, qh_REAL_1, facet->center[k]); + qh_fprintf(fp, 9067, qh_REAL_1, facet->center[k]); }else { for (k=0; k < num; k++) - fprintf (fp, qh_REAL_1, qh_INFINITE); + qh_fprintf(fp, 9068, qh_REAL_1, qh_INFINITE); } }else /* qh CENTERtype == qh_AScentrum */ { num= qh hull_dim; - if (format == qh_PRINTtriangles && qh DELAUNAY) + if (format == qh_PRINTtriangles && qh DELAUNAY) num--; - if (!facet->center) - facet->center= qh_getcentrum (facet); + if (!facet->center) + facet->center= qh_getcentrum(facet); for (k=0; k < num; k++) - fprintf (fp, qh_REAL_1, facet->center[k]); + qh_fprintf(fp, 9069, qh_REAL_1, facet->center[k]); } if (format == qh_PRINTgeom && num == 2) - fprintf (fp, " 0\n"); + qh_fprintf(fp, 9070, " 0\n"); else - fprintf (fp, "\n"); + 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 @@ -1552,36 +1620,36 @@ void qh_printcenter (FILE *fp, int format, char *string, facetT *facet) { returns: defines facet->center if needed */ -void qh_printcentrum (FILE *fp, facetT *facet, realT radius) { +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); + facet->center= qh_getcentrum(facet); centrum= facet->center; }else { - centrum= qh_getcentrum (facet); + centrum= qh_getcentrum(facet); tempcentrum= True; } - fprintf (fp, "{appearance {-normal -edge normscale 0} "); + qh_fprintf(fp, 9072, "{appearance {-normal -edge normscale 0} "); if (qh firstcentrum) { qh firstcentrum= False; - fprintf (fp, "{INST geom { define centrum CQUAD # f%d\n\ + 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 - fprintf (fp, "{INST geom { : centrum } transform { # f%d\n", facet->id); + 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--; ) { + for (k=qh hull_dim; k--; ) { xaxis[k]= projpt[k] - centrum[k]; normal[k]= facet->normal[k]; } @@ -1593,78 +1661,78 @@ void qh_printcentrum (FILE *fp, facetT *facet, realT radius) { qh_projectdim3 (normal, normal); qh_normalize2 (normal, qh PRINTdim, True, NULL, NULL); } - qh_crossproduct (3, xaxis, normal, yaxis); - fprintf (fp, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]); - fprintf (fp, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]); - fprintf (fp, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]); + qh_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); - fprintf (fp, "1 }}}\n"); - qh_memfree (projpt, qh normal_size); - qh_printpointvect (fp, centrum, facet->normal, NULL, radius, green); + 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); + 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, int format, facetT *facetlist, setT *facets, boolT printall) { +void qh_printend(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) { int num; facetT *facet, **facetp; if (!qh printoutnum) - fprintf (qh ferr, "qhull warning: no facets printed\n"); + 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); + qh_printend4geom(fp, facet,&num, printall); + FOREACHfacet_(facets) + qh_printend4geom(fp, facet, &num, printall); if (num != qh ridgeoutnum || qh printoutvar != qh ridgeoutnum) { - fprintf (qh ferr, "qhull internal error (qh_printend): number of ridges %d != number printed %d and at end %d\n", qh ridgeoutnum, qh printoutvar, num); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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 - fprintf(fp, "}\n"); + qh_fprintf(fp, 9079, "}\n"); break; case qh_PRINTinner: case qh_PRINTnormals: case qh_PRINTouter: - if (qh CDDoutput) - fprintf (fp, "end\n"); + if (qh CDDoutput) + qh_fprintf(fp, 9080, "end\n"); break; case qh_PRINTmaple: - fprintf(fp, "));\n"); + qh_fprintf(fp, 9081, "));\n"); break; case qh_PRINTmathematica: - fprintf(fp, "}\n"); + qh_fprintf(fp, 9082, "}\n"); break; case qh_PRINTpoints: if (qh CDDoutput) - fprintf (fp, "end\n"); + qh_fprintf(fp, 9083, "end\n"); 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 @@ -1672,14 +1740,14 @@ void qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT p design: computes color for facet from its normal - prints each ridge of facet + prints each ridge of facet */ -void qh_printend4geom (FILE *fp, facetT *facet, int *nump, boolT printall) { +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)) @@ -1697,22 +1765,22 @@ void qh_printend4geom (FILE *fp, facetT *facet, int *nump, boolT printall) { if (facet->simplicial) { FOREACHneighbor_(facet) { if (neighbor->visitid != qh visit_id) { - if (fp) - fprintf (fp, "3 %d %d %d %8.4g %8.4g %8.4g 1 # f%d f%d\n", - 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2], - facet->id, neighbor->id); - num++; + 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) - fprintf (fp, "3 %d %d %d %8.4g %8.4g %8.4g 1 #r%d f%d f%d\n", - 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2], - ridge->id, facet->id, neighbor->id); - num++; + 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++; } } } @@ -1721,46 +1789,46 @@ void qh_printend4geom (FILE *fp, facetT *facet, int *nump, boolT printall) { /*-<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, int printall) { +void qh_printextremes(FILE *fp, facetT *facetlist, setT *facets, int printall) { setT *vertices, *points; pointT *point; vertexT *vertex, **vertexp; int id; int numpoints=0, point_i, point_n; - int allpoints= qh num_points + qh_setsize (qh other_points); + 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); + points= qh_settemp(allpoints); + qh_setzero(points, 0, allpoints); + vertices= qh_facetvertices(facetlist, facets, printall); FOREACHvertex_(vertices) { - id= qh_pointid (vertex->point); + id= qh_pointid(vertex->point); if (id >= 0) { SETelem_(points, id)= vertex->point; numpoints++; } } - qh_settempfree (&vertices); - fprintf (fp, "%d\n", numpoints); + qh_settempfree(&vertices); + qh_fprintf(fp, 9086, "%d\n", numpoints); FOREACHpoint_i_(points) { - if (point) - fprintf (fp, "%d\n", point_i); + if (point) + qh_fprintf(fp, 9087, "%d\n", point_i); } - qh_settempfree (&points); + 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 @@ -1770,17 +1838,17 @@ void qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall) errors if facets form a loop does not print coplanar points */ -void qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall) { +void qh_printextremes_2d(FILE *fp, facetT *facetlist, setT *facets, int printall) { int numfacets, numridges, totneighbors, numcoplanars, numsimplicial, numtricoplanars; setT *vertices; facetT *facet, *startfacet, *nextfacet; vertexT *vertexA, *vertexB; - qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, + qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial, &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* marks qh visit_id */ - vertices= qh_facetvertices (facetlist, facets, printall); - fprintf(fp, "%d\n", qh_setsize (vertices)); - qh_settempfree (&vertices); + 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); @@ -1797,18 +1865,18 @@ void qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printal nextfacet= SETsecondt_(facet->neighbors, facetT); } if (facet->visitid == qh visit_id) { - fprintf(qh ferr, "qh_printextremes_2d: loop in facet list. facet %d nextfacet %d\n", + 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; - fprintf(fp, "%d\n", qh_pointid (vertexA->point)); + 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; - fprintf(fp, "%d\n", qh_pointid (vertexB->point)); + vertexB->visitid= qh vertex_visit; + qh_fprintf(fp, 9090, "%d\n", qh_pointid(vertexB->point)); } } facet->visitid= qh visit_id; @@ -1818,23 +1886,23 @@ void qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printal /*-<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, int printall) { +void qh_printextremes_d(FILE *fp, facetT *facetlist, setT *facets, int printall) { setT *vertices; vertexT *vertex, **vertexp; boolT upperseen, lowerseen; facetT *neighbor, **neighborp; int numpoints=0; - vertices= qh_facetvertices (facetlist, facets, printall); + vertices= qh_facetvertices(facetlist, facets, printall); qh_vertexneighbors(); FOREACHvertex_(vertices) { upperseen= lowerseen= False; @@ -1850,17 +1918,17 @@ void qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall }else vertex->seen= False; } - fprintf (fp, "%d\n", numpoints); + qh_fprintf(fp, 9091, "%d\n", numpoints); FOREACHvertex_(vertices) { if (vertex->seen) - fprintf (fp, "%d\n", qh_pointid (vertex->point)); + qh_fprintf(fp, 9092, "%d\n", qh_pointid(vertex->point)); } - qh_settempfree (&vertices); + 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 @@ -1869,18 +1937,18 @@ void qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall */ void qh_printfacet(FILE *fp, facetT *facet) { - qh_printfacetheader (fp, facet); + qh_printfacetheader(fp, facet); if (facet->ridges) - qh_printfacetridges (fp, facet); + 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 @@ -1891,49 +1959,49 @@ void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]) { realT mindist, innerplane, outerplane; int k; - qh_facet2point (facet, &point0, &point1, &mindist); - qh_geomplanes (facet, &outerplane, &innerplane); + 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--; ) + 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); + 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. + 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]) { + facetT *facet, realT offset, realT color[3]) { pointT *p1= point1, *p2= point2; - fprintf(fp, "VECT 1 2 1 2 1 # f%d\n", facet->id); + 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); + p1= qh_projectpoint(p1, facet, -offset); + p2= qh_projectpoint(p2, facet, -offset); } - fprintf(fp, "%8.4g %8.4g %8.4g\n%8.4g %8.4g %8.4g\n", + 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_memfree(p1, qh normal_size); + qh_memfree(p2, qh normal_size); } - fprintf(fp, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]); + 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 @@ -1946,26 +2014,26 @@ void qh_printfacet2math(FILE *fp, facetT *facet, int format, int notfirst) { pointT *point0, *point1; realT mindist; char *pointfmt; - - qh_facet2point (facet, &point0, &point1, &mindist); + + qh_facet2point(facet, &point0, &point1, &mindist); if (notfirst) - fprintf(fp, ","); + 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"; - fprintf(fp, pointfmt, point0[0], point0[1], point1[0], point1[1]); - qh_memfree (point1, qh normal_size); - qh_memfree (point0, qh normal_size); + 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) + if DOintersections, prints ridges to unvisited neighbors(qh visit_id) notes uses facet->visitid for intersections and ridges @@ -1980,15 +2048,15 @@ void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) { int cntvertices, k; realT black[3]={0, 0, 0}, green[3]={0, 1, 0}; - qh_geomplanes (facet, &outerplane, &innerplane); - vertices= qh_facet3vertex (facet); /* oriented */ + 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); + qh_setappend(&projectedpoints, projpt); } if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner)) qh_printfacet3geom_points(fp, projectedpoints, facet, outerplane, color); @@ -1999,7 +2067,7 @@ void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) { qh_printfacet3geom_points(fp, projectedpoints, facet, innerplane, color); } FOREACHpoint_(projectedpoints) - qh_memfree (point, qh normal_size); + qh_memfree(point, qh normal_size); qh_settempfree(&projectedpoints); qh_settempfree(&vertices); if ((qh DOintersections || qh PRINTridges) @@ -2013,7 +2081,7 @@ void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) { if (qh PRINTridges) { vertexA= SETfirstt_(ridge->vertices, vertexT); vertexB= SETsecondt_(ridge->vertices, vertexT); - qh_printline3geom (fp, vertexA->point, vertexB->point, green); + qh_printline3geom(fp, vertexA->point, vertexB->point, green); } } } @@ -2022,9 +2090,9 @@ void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) { /*-<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. + 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 */ @@ -2033,36 +2101,36 @@ void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offs pointT *point, **pointp; setT *printpoints; - fprintf(fp, "{ OFF %d 1 1 # f%d\n", n, facet->id); + 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)); + printpoints= qh_settemp(n); + FOREACHpoint_(points) + qh_setappend(&printpoints, qh_projectpoint(point, facet, -offset)); }else printpoints= points; FOREACHpoint_(printpoints) { for (k=0; k < qh hull_dim; k++) { if (k == qh DROPdim) - fprintf(fp, "0 "); + qh_fprintf(fp, 9099, "0 "); else - fprintf(fp, "%8.4g ", point[k]); + qh_fprintf(fp, 9100, "%8.4g ", point[k]); } if (printpoints != points) - qh_memfree (point, qh normal_size); - fprintf (fp, "\n"); + qh_memfree(point, qh normal_size); + qh_fprintf(fp, 9101, "\n"); } if (printpoints != points) - qh_settempfree (&printpoints); - fprintf(fp, "%d ", n); - for(i= 0; i < n; i++) - fprintf(fp, "%d ", i); - fprintf(fp, "%8.4g %8.4g %8.4g 1.0 }\n", color[0], color[1], color[2]); + 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. @@ -2082,16 +2150,16 @@ void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { 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); + 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--; ) + for (k=3; k--; ) color[k]= 1.0 - color[k]; qh_printfacet3geom_points(fp, points, facet, innerplane, color); } @@ -2102,16 +2170,16 @@ void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { 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); + vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim, + SETindex_(facet->neighbors, neighbor), 0); if (qh DOintersections) - qh_printhyperplaneintersection(fp, facet, neighbor, vertices, black); + 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_printline3geom(fp, vertexA->point, vertexB->point, green); } - qh_setfree(&vertices); + qh_setfree(&vertices); } } } @@ -2119,7 +2187,7 @@ void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { /*-<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 @@ -2128,30 +2196,30 @@ void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { use %16.8f since Mathematica 2.2 does not handle exponential format see qh_printfacet2math */ -void qh_printfacet3math (FILE *fp, facetT *facet, int format, int notfirst) { +void qh_printfacet3math(FILE *fp, facetT *facet, int format, int notfirst) { vertexT *vertex, **vertexp; setT *points, *vertices; pointT *point, **pointp; boolT firstpoint= True; realT dist; char *pointfmt, *endfmt; - + if (notfirst) - fprintf(fp, ",\n"); - vertices= qh_facet3vertex (facet); - points= qh_settemp (qh_setsize (vertices)); + 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); + qh_setappend(&points, point); } if (format == qh_PRINTmaple) { - fprintf(fp, "["); + qh_fprintf(fp, 9106, "["); pointfmt= "[%16.8f, %16.8f, %16.8f]"; endfmt= "]"; }else { - fprintf(fp, "Polygon[{"); + qh_fprintf(fp, 9107, "Polygon[{"); pointfmt= "{%16.8f, %16.8f, %16.8f}"; endfmt= "}]"; } @@ -2159,20 +2227,20 @@ void qh_printfacet3math (FILE *fp, facetT *facet, int format, int notfirst) { if (firstpoint) firstpoint= False; else - fprintf(fp, ",\n"); - fprintf(fp, pointfmt, point[0], point[1], point[2]); + 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_memfree(point, qh normal_size); qh_settempfree(&points); qh_settempfree(&vertices); - fprintf(fp, endfmt); + 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 @@ -2184,25 +2252,25 @@ void qh_printfacet3vertex(FILE *fp, facetT *facet, int format) { vertexT *vertex, **vertexp; setT *vertices; - vertices= qh_facet3vertex (facet); + vertices= qh_facet3vertex(facet); if (format == qh_PRINToff) - fprintf (fp, "%d ", qh_setsize (vertices)); - FOREACHvertex_(vertices) - fprintf (fp, "%d ", qh_pointid(vertex->point)); - fprintf (fp, "\n"); + qh_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() */ @@ -2213,38 +2281,38 @@ void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) { 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) + if (neighbor->visitid == qh visit_id) continue; if (qh PRINTtransparent && !neighbor->good) - continue; + continue; if (qh DOintersections) qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, color); else { - if (qh DROPdim >= 0) - fprintf(fp, "OFF 3 1 1 # f%d\n", facet->id); + if (qh DROPdim >= 0) + qh_fprintf(fp, 9114, "OFF 3 1 1 # f%d\n", facet->id); else { - qh printoutvar++; - fprintf (fp, "# r%d between f%d f%d\n", ridge->id, facet->id, neighbor->id); + 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) - fprintf(fp, "%8.4g ", point[k]); - } - fprintf (fp, "\n"); - qh_memfree (point, qh normal_size); + 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) - fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]); + qh_fprintf(fp, 9118, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]); } } } /* printfacet4geom_nonsimplicial */ @@ -2252,7 +2320,7 @@ void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) { /*-<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) @@ -2265,7 +2333,7 @@ void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { facetT *neighbor, **neighborp; vertexT *vertex, **vertexp; int k; - + facet->visitid= qh visit_id; if (qh PRINTnoplanes || (facet->visible && qh NEWfacets)) return; @@ -2273,28 +2341,28 @@ void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { 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); + continue; + vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim, + SETindex_(facet->neighbors, neighbor), 0); if (qh DOintersections) qh_printhyperplaneintersection(fp, facet, neighbor, vertices, color); else { - if (qh DROPdim >= 0) - fprintf(fp, "OFF 3 1 1 # ridge between f%d f%d\n", - facet->id, neighbor->id); + 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++; - fprintf (fp, "# ridge between f%d f%d\n", facet->id, neighbor->id); + 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) - fprintf(fp, "%8.4g ", vertex->point[k]); - } - fprintf (fp, "\n"); + 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) - fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]); + 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); } @@ -2303,7 +2371,7 @@ void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]) { /*-<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 @@ -2316,23 +2384,23 @@ void qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int for return; FOREACHridge_(facet->ridges) { if (format == qh_PRINTtriangles) - fprintf(fp, "%d ", qh hull_dim); - fprintf(fp, "%d ", id); + qh_fprintf(fp, 9124, "%d ", qh hull_dim); + qh_fprintf(fp, 9125, "%d ", id); if ((ridge->top == facet) ^ qh_ORIENTclock) { FOREACHvertex_(ridge->vertices) - fprintf(fp, "%d ", qh_pointid(vertex->point)); + qh_fprintf(fp, 9126, "%d ", qh_pointid(vertex->point)); }else { FOREACHvertexreverse12_(ridge->vertices) - fprintf(fp, "%d ", qh_pointid(vertex->point)); + qh_fprintf(fp, 9127, "%d ", qh_pointid(vertex->point)); } - fprintf(fp, "\n"); + 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 @@ -2343,27 +2411,28 @@ void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format) { vertexT *vertex, **vertexp; if (format == qh_PRINToff || format == qh_PRINTtriangles) - fprintf (fp, "%d ", qh_setsize (facet->vertices)); - if ((facet->toporient ^ qh_ORIENTclock) + qh_fprintf(fp, 9129, "%d ", qh_setsize(facet->vertices)); + if ((facet->toporient ^ qh_ORIENTclock) || (qh hull_dim > 2 && !facet->simplicial)) { FOREACHvertex_(facet->vertices) - fprintf(fp, "%d ", qh_pointid(vertex->point)); + qh_fprintf(fp, 9130, "%d ", qh_pointid(vertex->point)); }else { FOREACHvertexreverse12_(facet->vertices) - fprintf(fp, "%d ", qh_pointid(vertex->point)); + qh_fprintf(fp, 9131, "%d ", qh_pointid(vertex->point)); } - fprintf(fp, "\n"); + 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; @@ -2371,134 +2440,134 @@ void qh_printfacetheader(FILE *fp, facetT *facet) { realT dist; if (facet == qh_MERGEridge) { - fprintf (fp, " MERGEridge\n"); + qh_fprintf(fp, 9133, " MERGEridge\n"); return; }else if (facet == qh_DUPLICATEridge) { - fprintf (fp, " DUPLICATEridge\n"); + qh_fprintf(fp, 9134, " DUPLICATEridge\n"); return; }else if (!facet) { - fprintf (fp, " NULLfacet\n"); + qh_fprintf(fp, 9135, " NULLfacet\n"); return; } qh old_randomdist= qh RANDOMdist; qh RANDOMdist= False; - fprintf(fp, "- f%d\n", facet->id); - fprintf(fp, " - flags:"); - if (facet->toporient) - fprintf(fp, " top"); + qh_fprintf(fp, 9136, "- f%d\n", facet->id); + qh_fprintf(fp, 9137, " - flags:"); + if (facet->toporient) + qh_fprintf(fp, 9138, " top"); else - fprintf(fp, " bottom"); + qh_fprintf(fp, 9139, " bottom"); if (facet->simplicial) - fprintf(fp, " simplicial"); + qh_fprintf(fp, 9140, " simplicial"); if (facet->tricoplanar) - fprintf(fp, " tricoplanar"); + qh_fprintf(fp, 9141, " tricoplanar"); if (facet->upperdelaunay) - fprintf(fp, " upperDelaunay"); + qh_fprintf(fp, 9142, " upperDelaunay"); if (facet->visible) - fprintf(fp, " visible"); + qh_fprintf(fp, 9143, " visible"); if (facet->newfacet) - fprintf(fp, " new"); + qh_fprintf(fp, 9144, " new"); if (facet->tested) - fprintf(fp, " tested"); + qh_fprintf(fp, 9145, " tested"); if (!facet->good) - fprintf(fp, " notG"); + qh_fprintf(fp, 9146, " notG"); if (facet->seen) - fprintf(fp, " seen"); + qh_fprintf(fp, 9147, " seen"); if (facet->coplanar) - fprintf(fp, " coplanar"); + qh_fprintf(fp, 9148, " coplanar"); if (facet->mergehorizon) - fprintf(fp, " mergehorizon"); + qh_fprintf(fp, 9149, " mergehorizon"); if (facet->keepcentrum) - fprintf(fp, " keepcentrum"); + qh_fprintf(fp, 9150, " keepcentrum"); if (facet->dupridge) - fprintf(fp, " dupridge"); + qh_fprintf(fp, 9151, " dupridge"); if (facet->mergeridge && !facet->mergeridge2) - fprintf(fp, " mergeridge1"); + qh_fprintf(fp, 9152, " mergeridge1"); if (facet->mergeridge2) - fprintf(fp, " mergeridge2"); + qh_fprintf(fp, 9153, " mergeridge2"); if (facet->newmerge) - fprintf(fp, " newmerge"); - if (facet->flipped) - fprintf(fp, " flipped"); - if (facet->notfurthest) - fprintf(fp, " notfurthest"); + qh_fprintf(fp, 9154, " newmerge"); + if (facet->flipped) + qh_fprintf(fp, 9155, " flipped"); + if (facet->notfurthest) + qh_fprintf(fp, 9156, " notfurthest"); if (facet->degenerate) - fprintf(fp, " degenerate"); + qh_fprintf(fp, 9157, " degenerate"); if (facet->redundant) - fprintf(fp, " redundant"); - fprintf(fp, "\n"); + qh_fprintf(fp, 9158, " redundant"); + qh_fprintf(fp, 9159, "\n"); if (facet->isarea) - fprintf(fp, " - area: %2.2g\n", facet->f.area); + qh_fprintf(fp, 9160, " - area: %2.2g\n", facet->f.area); else if (qh NEWfacets && facet->visible && facet->f.replace) - fprintf(fp, " - replacement: f%d\n", facet->f.replace->id); + qh_fprintf(fp, 9161, " - replacement: f%d\n", facet->f.replace->id); else if (facet->newfacet) { if (facet->f.samecycle && facet->f.samecycle != facet) - fprintf(fp, " - shares same visible/horizon as f%d\n", facet->f.samecycle->id); + 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) - fprintf(fp, " - owner of normal & centrum is facet f%d\n", facet->f.triowner->id); + qh_fprintf(fp, 9163, " - owner of normal & centrum is facet f%d\n", facet->f.triowner->id); }else if (facet->f.newcycle) - fprintf(fp, " - was horizon to f%d\n", facet->f.newcycle->id); + qh_fprintf(fp, 9164, " - was horizon to f%d\n", facet->f.newcycle->id); if (facet->nummerge) - fprintf(fp, " - merges: %d\n", facet->nummerge); + qh_fprintf(fp, 9165, " - merges: %d\n", facet->nummerge); qh_printpointid(fp, " - normal: ", qh hull_dim, facet->normal, -1); - fprintf(fp, " - offset: %10.7g\n", facet->offset); + qh_fprintf(fp, 9166, " - offset: %10.7g\n", facet->offset); if (qh CENTERtype == qh_ASvoronoi || facet->center) - qh_printcenter (fp, qh_PRINTfacets, " - center: ", facet); + qh_printcenter(fp, qh_PRINTfacets, " - center: ", facet); #if qh_MAXoutside if (facet->maxoutside > qh DISTround) - fprintf(fp, " - maxoutside: %10.7g\n", facet->maxoutside); + 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) { - fprintf(fp, " - outside set (furthest p%d):\n", qh_pointid(furthest)); + 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_printpoint(fp, " ", point); + }else if (qh_setsize(facet->outsideset) < 21) { qh_printpoints(fp, " - outside set:", facet->outsideset); }else { - fprintf(fp, " - outside set: %d points.", qh_setsize(facet->outsideset)); + qh_fprintf(fp, 9169, " - outside set: %d points.", qh_setsize(facet->outsideset)); qh_printpoint(fp, " Furthest", furthest); } #if !qh_COMPUTEfurthest - fprintf(fp, " - furthest distance= %2.2g\n", facet->furthestdist); + 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) { - fprintf(fp, " - coplanar set (furthest p%d):\n", qh_pointid(furthest)); + 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_printpoint(fp, " ", point); + }else if (qh_setsize(facet->coplanarset) < 21) { qh_printpoints(fp, " - coplanar set:", facet->coplanarset); }else { - fprintf(fp, " - coplanar set: %d points.", qh_setsize(facet->coplanarset)); + qh_fprintf(fp, 9172, " - coplanar set: %d points.", qh_setsize(facet->coplanarset)); qh_printpoint(fp, " Furthest", furthest); } zinc_(Zdistio); - qh_distplane (furthest, facet, &dist); - fprintf(fp, " furthest distance= %2.2g\n", dist); + qh_distplane(furthest, facet, &dist); + qh_fprintf(fp, 9173, " furthest distance= %2.2g\n", dist); } - qh_printvertices (fp, " - vertices:", facet->vertices); - fprintf(fp, " - neighboring facets: "); + qh_printvertices(fp, " - vertices:", facet->vertices); + qh_fprintf(fp, 9174, " - neighboring facets:"); FOREACHneighbor_(facet) { if (neighbor == qh_MERGEridge) - fprintf(fp, " MERGE"); + qh_fprintf(fp, 9175, " MERGE"); else if (neighbor == qh_DUPLICATEridge) - fprintf(fp, " DUP"); + qh_fprintf(fp, 9176, " DUP"); else - fprintf(fp, " f%d", neighbor->id); + qh_fprintf(fp, 9177, " f%d", neighbor->id); } - fprintf(fp, "\n"); + 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 @@ -2506,6 +2575,7 @@ void qh_printfacetheader(FILE *fp, facetT *facet) { 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; @@ -2514,52 +2584,52 @@ void qh_printfacetridges(FILE *fp, facetT *facet) { if (facet->visible && qh NEWfacets) { - fprintf(fp, " - ridges (ids may be garbage):"); + qh_fprintf(fp, 9179, " - ridges(ids may be garbage):"); FOREACHridge_(facet->ridges) - fprintf(fp, " r%d", ridge->id); - fprintf(fp, "\n"); + qh_fprintf(fp, 9180, " r%d", ridge->id); + qh_fprintf(fp, 9181, "\n"); }else { - fprintf(fp, " - ridges:\n"); + 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); - } + 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++; - } - } + FOREACHridge_(facet->ridges) { + if (otherfacet_(ridge,facet) == neighbor) { + ridge->seen= True; + qh_printridge(fp, ridge); + numridges++; + } + } } } - if (numridges != qh_setsize (facet->ridges)) { - fprintf (fp, " - all ridges:"); - FOREACHridge_(facet->ridges) - fprintf (fp, " r%d", ridge->id); - fprintf (fp, "\n"); + 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); + 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 @@ -2574,362 +2644,193 @@ void qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT qh old_randomdist= qh RANDOMdist; qh RANDOMdist= False; if (qh CDDoutput && (format == qh_PRINTcentrums || format == qh_PRINTpointintersect || format == qh_PRINToff)) - fprintf (qh ferr, "qhull warning: CDD format is not available for centrums, halfspace\nintersections, and OFF file format.\n"); + 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); - fprintf (fp, "%d 1\n", qh hull_dim); - qh_printpointid (fp, NULL, qh hull_dim, center, -1); - qh_memfree (center, qh normal_size); - qh_settempfree (&vertices); + 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_memfree(center, qh normal_size); + qh_settempfree(&vertices); }else if (format == qh_PRINTextremes) { if (qh DELAUNAY) - qh_printextremes_d (fp, facetlist, facets, printall); + 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); + qh_printextremes_2d(fp, facetlist, facets, printall); + else + qh_printextremes(fp, facetlist, facets, printall); }else if (format == qh_PRINToptions) - fprintf(fp, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options); + 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); + qh_printpoints_out(fp, facetlist, facets, printall); else if (format == qh_PRINTqhull) - fprintf (fp, "%s | %s\n", qh rbox_command, qh qhull_command); + qh_fprintf(fp, 9188, "%s | %s\n", qh rbox_command, qh qhull_command); else if (format == qh_PRINTsize) { - fprintf (fp, "0\n2 "); - fprintf (fp, qh_REAL_1, qh totarea); - fprintf (fp, qh_REAL_1, qh totvol); - fprintf (fp, "\n"); + 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, + qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial, &totneighbors, &numridges, &numcoplanars, &numtricoplanars); - vertices= qh_facetvertices (facetlist, facets, printall); - fprintf (fp, "10 %d %d %d %d %d %d %d %d %d %d\n2 ", qh hull_dim, - qh num_points + qh_setsize (qh other_points), + 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); - fprintf (fp, qh_REAL_2n, outerplane, innerplane); + 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); + qh_printvneighbors(fp, facetlist, facets, printall); else if (qh VORONOI && format == qh_PRINToff) - qh_printvoronoi (fp, format, facetlist, facets, printall); + 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 + 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); + qh_printvdiagram(fp, format, facetlist, facets, printall); else { - qh_printbegin (fp, format, facetlist, facets, printall); + 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_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="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) - fprintf(fp, "\n\ -A Qhull error has occurred. Qhull should have corrected the above\n\ -precision error. Please send the input and all of the output to\n\ -qhull_bug@qhull.org\n"); - else if (!qh_QUICKhelp) { - fprintf(fp, "\n\ -Precision problems were detected during construction of the convex hull.\n\ -This occurs because convex hull algorithms assume that calculations are\n\ -exact, but floating-point arithmetic has roundoff errors.\n\ -\n\ -To correct for precision problems, do not use 'Q0'. By default, Qhull\n\ -selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\ -Qhull joggles the input to prevent precision problems. See \"Imprecision\n\ -in Qhull\" (qh-impre.htm).\n\ -\n\ -If you use 'Q0', the output may include\n\ -coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\ -Qhull may produce a ridge with four neighbors or two facets with the same \n\ -vertices. Qhull reports these events when they occur. It stops when a\n\ -concave ridge, flipped facet, or duplicate facet occurs.\n"); -#if REALfloat - fprintf (fp, "\ -\n\ -Qhull is currently using single precision arithmetic. The following\n\ -will probably remove the precision problems:\n\ - - recompile qhull for double precision (#define REALfloat 0 in user.h).\n"); -#endif - if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4) - fprintf( fp, "\ -\n\ -When computing the Delaunay triangulation of coordinates > 1.0,\n\ - - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n"); - if (qh DELAUNAY && !qh ATinfinity) - fprintf( fp, "\ -When computing the Delaunay triangulation:\n\ - - use 'Qz' to add a point at-infinity. This reduces precision problems.\n"); - - fprintf(fp, "\ -\n\ -If you need triangular output:\n\ - - use option 'Qt' to triangulate the output\n\ - - use option 'QJ' to joggle the input points and remove precision errors\n\ - - use option 'Ft'. It triangulates non-simplicial facets with added points.\n\ -\n\ -If you must use 'Q0',\n\ -try one or more of the following options. They can not guarantee an output.\n\ - - use 'QbB' to scale the input to a cube.\n\ - - use 'Po' to produce output and prevent partitioning for flipped facets\n\ - - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\ - - use 'En' to specify a maximum roundoff error less than %2.2g.\n\ - - options 'Qf', 'Qbb', and 'QR0' may also help\n", - qh DISTround); - fprintf(fp, "\ -\n\ -To guarantee simplicial output:\n\ - - use option 'Qt' to triangulate the output\n\ - - use option 'QJ' to joggle the input points and remove precision errors\n\ - - use option 'Ft' to triangulate the output by adding points\n\ - - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\ -"); - } -} /* printhelp_degenerate */ - - -/*-<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; - - fprintf(fp, "\n\ -The input to qhull appears to be less than %d dimensional, or a\n\ -computation has overflowed.\n\n\ -Qhull could not construct a clearly convex simplex from points:\n", - qh hull_dim); - qh_printvertexlist (fp, "", qh facet_list, NULL, qh_ALL); - if (!qh_QUICKhelp) - fprintf(fp, "\n\ -The center point is coplanar with a facet, or a vertex is coplanar\n\ -with a neighboring facet. The maximum round off error for\n\ -computing distances is %2.2g. The center point, facets and distances\n\ -to the center point are as follows:\n\n", qh DISTround); - qh_printpointid (fp, "center point", qh hull_dim, qh interior_point, -1); - fprintf (fp, "\n"); - FORALLfacets { - fprintf (fp, "facet"); - FOREACHvertex_(facet->vertices) - fprintf (fp, " p%d", qh_pointid(vertex->point)); - zinc_(Zdistio); - qh_distplane(qh interior_point, facet, &dist); - fprintf (fp, " distance= %4.2g\n", dist); - } - if (!qh_QUICKhelp) { - if (qh HALFspace) - fprintf (fp, "\n\ -These points are the dual of the given halfspaces. They indicate that\n\ -the intersection is degenerate.\n"); - fprintf (fp,"\n\ -These points either have a maximum or minimum x-coordinate, or\n\ -they maximize the determinant for k coordinates. Trial points\n\ -are first selected from points that maximize a coordinate.\n"); - if (qh hull_dim >= qh_INITIALmax) - fprintf (fp, "\n\ -Because of the high dimension, the min x-coordinate and max-coordinate\n\ -points are used if the determinant is non-zero. Option 'Qs' will\n\ -do a better, though much slower, job. Instead of 'Qs', you can change\n\ -the points by randomly rotating the input with 'QR0'.\n"); - } - fprintf (fp, "\nThe min and max coordinates for each dimension are:\n"); - for (k=0; k < qh hull_dim; k++) { - min= REALmax; - max= -REALmin; - for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) { - maximize_(max, *coord); - minimize_(min, *coord); - } - fprintf (fp, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min); - } - if (!qh_QUICKhelp) { - fprintf (fp, "\n\ -If the input should be full dimensional, you have several options that\n\ -may determine an initial simplex:\n\ - - use 'QJ' to joggle the input and make it full dimensional\n\ - - use 'QbB' to scale the points to the unit cube\n\ - - use 'QR0' to randomly rotate the input for different maximum points\n\ - - use 'Qs' to search all points for the initial simplex\n\ - - use 'En' to specify a maximum roundoff error less than %2.2g.\n\ - - trace execution with 'T3' to see the determinant for each point.\n", - qh DISTround); -#if REALfloat - fprintf (fp, "\ - - recompile qhull for double precision (#define REALfloat 0 in qhull.h).\n"); -#endif - fprintf (fp, "\n\ -If the input is lower dimensional:\n\ - - use 'QJ' to joggle the input and make it full dimensional\n\ - - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\ - pick the coordinate with the least range. The hull will have the\n\ - correct topology.\n\ - - determine the flat containing the points, rotate the points\n\ - into a coordinate plane, and delete the other coordinates.\n\ - - add one or more points to make the input full dimensional.\n\ -"); - if (qh DELAUNAY && !qh ATinfinity) - fprintf (fp, "\n\n\ -This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\ - - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\ - - or use 'QJ' to joggle the input and avoid co-circular data\n"); - } -} /* printhelp_singular */ - /*-<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]) { + setT *vertices, realT color[3]) { realT costheta, denominator, dist1, dist2, s, t, mindenom, p[4]; vertexT *vertex, **vertexp; int i, k; boolT nearzero1, nearzero2; - + costheta= qh_getangle(facet1->normal, facet2->normal); denominator= 1 - costheta * costheta; i= qh_setsize(vertices); if (qh hull_dim == 3) - fprintf(fp, "VECT 1 %d 1 %d 1 ", i, i); + qh_fprintf(fp, 9195, "VECT 1 %d 1 %d 1 ", i, i); else if (qh hull_dim == 4 && qh DROPdim >= 0) - fprintf(fp, "OFF 3 1 1 "); + qh_fprintf(fp, 9196, "OFF 3 1 1 "); else qh printoutvar++; - fprintf (fp, "# intersect f%d f%d\n", facet1->id, facet2->id); + 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); + 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--; ) + for (k=qh hull_dim; k--; ) p[k]= vertex->point[k] + facet1->normal[k] * s + facet2->normal[k] * t; if (qh PRINTdim <= 3) { qh_projectdim3 (p, p); - fprintf(fp, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]); - }else - fprintf(fp, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]); + 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) - fprintf (fp, "p%d (coplanar facets)\n", qh_pointid (vertex->point)); + qh_fprintf(fp, 9200, "p%d(coplanar facets)\n", qh_pointid(vertex->point)); else - fprintf (fp, "projected p%d\n", qh_pointid (vertex->point)); + qh_fprintf(fp, 9201, "projected p%d\n", qh_pointid(vertex->point)); } if (qh hull_dim == 3) - fprintf(fp, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]); - else if (qh hull_dim == 4 && qh DROPdim >= 0) - fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]); + 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, + if pointA == pointB, it's a 1 point VECT */ -void qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]) { +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) || + if ((fabs(pA[0] - pB[0]) > 1e-3) || + (fabs(pA[1] - pB[1]) > 1e-3) || (fabs(pA[2] - pB[2]) > 1e-3)) { - fprintf (fp, "VECT 1 2 1 2 1\n"); - for (k= 0; k < 3; k++) - fprintf (fp, "%8.4g ", pB[k]); - fprintf (fp, " # p%d\n", qh_pointid (pointB)); + 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 - fprintf (fp, "VECT 1 1 1 1 1\n"); + qh_fprintf(fp, 9207, "VECT 1 1 1 1 1\n"); for (k=0; k < 3; k++) - fprintf (fp, "%8.4g ", pA[k]); - fprintf (fp, " # p%d\n", qh_pointid (pointA)); - fprintf (fp, "%8.4g %8.4g %8.4g 1\n", color[0], color[1], color[2]); + qh_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() + calls qh_findgood_all() bumps qh.visit_id */ -void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall) { +void qh_printneighborhood(FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall) { facetT *neighbor, **neighborp, *facet; setT *facets; if (format == qh_PRINTnone) return; - qh_findgood_all (qh facet_list); + qh_findgood_all(qh facet_list); if (facetA == facetB) facetB= NULL; - facets= qh_settemp (2*(qh_setsize (facetA->neighbors)+1)); + 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); + 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); + if (printall || !qh_skipfacet(neighbor)) + qh_setappend(&facets, neighbor); } } - qh_printfacets (fp, format, NULL, facets, printall); - qh_settempfree (&facets); + 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 @@ -2941,6 +2842,7 @@ void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, notes: nop if point is NULL prints id unless it is undefined (-1) + Same as QhullPoint's printPoint */ void qh_printpoint(FILE *fp, char *string, pointT *point) { int id= qh_pointid( point); @@ -2951,48 +2853,48 @@ void qh_printpoint(FILE *fp, char *string, pointT *point) { void qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id) { int k; realT r; /*bug fix*/ - + if (!point) return; if (string) { - fputs (string, fp); + qh_fprintf(fp, 9211, "%s", string); if (id != -1) - fprintf(fp, " p%d: ", id); + qh_fprintf(fp, 9212, " p%d: ", id); } - for(k= dim; k--; ) { + for (k=dim; k--; ) { r= *point++; if (string) - fprintf(fp, " %8.4g", r); + qh_fprintf(fp, 9213, " %8.4g", r); else - fprintf(fp, qh_REAL_1, r); + qh_fprintf(fp, 9214, qh_REAL_1, r); } - fprintf(fp, "\n"); + 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++) - fprintf (fp, "%8.4g ", p[k]); - fprintf (fp, " # p%d\n", qh_pointid (point)); + 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 +-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 @@ -3002,8 +2904,8 @@ void qh_printpoint3 (FILE *fp, pointT *point) { if no coplanar/interior points, same order as qh_printextremes */ -void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall) { - int allpoints= qh num_points + qh_setsize (qh other_points); +void qh_printpoints_out(FILE *fp, facetT *facetlist, setT *facets, int printall) { + int allpoints= qh num_points + qh_setsize(qh other_points); int numpoints=0, point_i, point_n; setT *vertices, *points; facetT *facet, **facetp; @@ -3011,11 +2913,11 @@ void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall vertexT *vertex, **vertexp; int id; - points= qh_settemp (allpoints); - qh_setzero (points, 0, allpoints); - vertices= qh_facetvertices (facetlist, facets, printall); + points= qh_settemp(allpoints); + qh_setzero(points, 0, allpoints); + vertices= qh_facetvertices(facetlist, facets, printall); FOREACHvertex_(vertices) { - id= qh_pointid (vertex->point); + id= qh_pointid(vertex->point); if (id >= 0) SETelem_(points, id)= vertex->point; } @@ -3024,7 +2926,7 @@ void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall if (!printall && qh_skipfacet(facet)) continue; FOREACHpoint_(facet->coplanarset) { - id= qh_pointid (point); + id= qh_pointid(point); if (id >= 0) SETelem_(points, id)= point; } @@ -3033,99 +2935,100 @@ void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall if (!printall && qh_skipfacet(facet)) continue; FOREACHpoint_(facet->coplanarset) { - id= qh_pointid (point); + id= qh_pointid(point); if (id >= 0) SETelem_(points, id)= point; } } } - qh_settempfree (&vertices); + qh_settempfree(&vertices); FOREACHpoint_i_(points) { if (point) numpoints++; } if (qh CDDoutput) - fprintf (fp, "%s | %s\nbegin\n%d %d real\n", qh rbox_command, + qh_fprintf(fp, 9218, "%s | %s\nbegin\n%d %d real\n", qh rbox_command, qh qhull_command, numpoints, qh hull_dim + 1); else - fprintf (fp, "%d\n%d\n", qh hull_dim, numpoints); + qh_fprintf(fp, 9219, "%d\n%d\n", qh hull_dim, numpoints); FOREACHpoint_i_(points) { if (point) { if (qh CDDoutput) - fprintf (fp, "1 "); - qh_printpoint (fp, NULL, point); + qh_fprintf(fp, 9220, "1 "); + qh_printpoint(fp, NULL, point); } } if (qh CDDoutput) - fprintf (fp, "end\n"); - qh_settempfree (&points); + 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]) { +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--; ) { + + for (k=qh hull_dim; k--; ) { if (center) diff[k]= point[k]-center[k]; - else if (normal) + 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--; ) + for (k=qh hull_dim; k--; ) pointA[k]= point[k]+diff[k] * radius; - qh_printline3geom (fp, point, pointA, color); -} /* printpointvect */ + 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); + 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) { - - fprintf(fp, " - r%d", ridge->id); + + qh_fprintf(fp, 9222, " - r%d", ridge->id); if (ridge->tested) - fprintf (fp, " tested"); + qh_fprintf(fp, 9223, " tested"); if (ridge->nonconvex) - fprintf (fp, " nonconvex"); - fprintf (fp, "\n"); - qh_printvertices (fp, " vertices:", ridge->vertices); + qh_fprintf(fp, 9224, " nonconvex"); + qh_fprintf(fp, 9225, "\n"); + qh_printvertices(fp, " vertices:", ridge->vertices); if (ridge->top && ridge->bottom) - fprintf(fp, " between f%d and f%d\n", - ridge->top->id, ridge->bottom->id); + 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 @@ -3136,7 +3039,7 @@ void qh_printspheres(FILE *fp, setT *vertices, realT radius) { vertexT *vertex, **vertexp; qh printoutnum++; - fprintf (fp, "{appearance {-edge -normal normscale 0} {\n\ + qh_fprintf(fp, 9227, "{appearance {-edge -normal normscale 0} {\n\ INST geom {define vsphere OFF\n\ 18 32 48\n\ \n\ @@ -3160,10 +3063,10 @@ INST geom {define vsphere OFF\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 7 6 \n\ +3 0 9 7 \n\ 3 0 11 9\n\ -3 1 6 8 \n\ +3 1 6 8 \n\ 3 1 8 14\n\ 3 1 13 6\n\ 3 1 14 13\n\ @@ -3192,28 +3095,28 @@ INST geom {define vsphere OFF\n\ 3 16 12 15\n\ 3 17 10 16\n} transforms { TLIST\n"); FOREACHvertex_(vertices) { - fprintf(fp, "%8.4g 0 0 0 # v%d\n 0 %8.4g 0 0\n0 0 %8.4g 0\n", + 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); - fprintf (fp, "1\n"); + qh_fprintf(fp, 9229, "1\n"); } - fprintf (fp, "}}}\n"); + qh_fprintf(fp, 9230, "}}}\n"); } /* printspheres */ /*---------------------------------------------- -printsummary- - see qhull.c + see qhulllib.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 @@ -3225,10 +3128,10 @@ INST geom {define vsphere OFF\n\ qh_eachvoronoi_all() notes: - if all facets are upperdelaunay, + if all facets are upperdelaunay, prints upper hull (furthest-site Voronoi diagram) */ -void qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) { +void qh_printvdiagram(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) { setT *vertices; int totcount, numcenters; boolT islower; @@ -3245,47 +3148,47 @@ void qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, bo innerouter= qh_RIDGEouter; printvridge= qh_printvnorm; }else { - fprintf(qh ferr, "qh_printvdiagram: unknown print format %d.\n", format); - qh_errexit (qh_ERRinput, NULL, NULL); + 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); + vertices= qh_markvoronoi(facetlist, facets, printall, &islower, &numcenters); totcount= qh_printvdiagram2 (NULL, NULL, vertices, innerouter, False); - fprintf (fp, "%d\n", totcount); + qh_fprintf(fp, 9231, "%d\n", totcount); totcount= qh_printvdiagram2 (fp, printvridge, vertices, innerouter, True /* inorder*/); - qh_settempfree (&vertices); + qh_settempfree(&vertices); #if 0 /* for testing qh_eachvoronoi_all */ - fprintf (fp, "\n"); + qh_fprintf(fp, 9232, "\n"); totcount= qh_eachvoronoi_all(fp, printvridge, qh UPPERdelaunay, innerouter, True /* inorder*/); - fprintf (fp, "%d\n", totcount); + 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_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 + total number of Voronoi ridges if printvridge, calls printvridge( fp, vertex, vertexA, centers) for each ridge [see qh_eachvoronoi()] - + see: qh_eachvoronoi_all() */ @@ -3294,23 +3197,24 @@ int qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RI int vertex_i, vertex_n; vertexT *vertex; - FORALLvertices + 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); + 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; @@ -3319,72 +3223,73 @@ void qh_printvertex(FILE *fp, vertexT *vertex) { realT r; /*bug fix*/ if (!vertex) { - fprintf (fp, " NULLvertex\n"); + qh_fprintf(fp, 9234, " NULLvertex\n"); return; } - fprintf(fp, "- p%d (v%d):", qh_pointid(vertex->point), vertex->id); + 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--; ) { + for (k=qh hull_dim; k--; ) { r= *point++; - fprintf(fp, " %5.2g", r); + qh_fprintf(fp, 9236, " %5.2g", r); } } if (vertex->deleted) - fprintf(fp, " deleted"); + qh_fprintf(fp, 9237, " deleted"); if (vertex->delridge) - fprintf (fp, " ridgedeleted"); - fprintf(fp, "\n"); + qh_fprintf(fp, 9238, " ridgedeleted"); + qh_fprintf(fp, 9239, "\n"); if (vertex->neighbors) { - fprintf(fp, " neighbors:"); + qh_fprintf(fp, 9240, " neighbors:"); FOREACHneighbor_(vertex) { if (++count % 100 == 0) - fprintf (fp, "\n "); - fprintf(fp, " f%d", neighbor->id); + qh_fprintf(fp, 9241, "\n "); + qh_fprintf(fp, 9242, " f%d", neighbor->id); } - fprintf(fp, "\n"); + 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, char* string, facetT *facetlist, +void qh_printvertexlist(FILE *fp, char* string, facetT *facetlist, setT *facets, boolT printall) { vertexT *vertex, **vertexp; setT *vertices; - - vertices= qh_facetvertices (facetlist, facets, printall); - fputs (string, fp); + + vertices= qh_facetvertices(facetlist, facets, printall); + qh_fprintf(fp, 9244, "%s", string); FOREACHvertex_(vertices) qh_printvertex(fp, vertex); - qh_settempfree (&vertices); + 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, char* string, setT *vertices) { vertexT *vertex, **vertexp; - - fputs (string, fp); - FOREACHvertex_(vertices) - fprintf (fp, " p%d (v%d)", qh_pointid(vertex->point), vertex->id); - fprintf(fp, "\n"); + + 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') @@ -3399,61 +3304,61 @@ void qh_printvertices(FILE *fp, char* string, setT *vertices) { for each point list vertex neighbors or coplanar facet */ -void qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall) { +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); + 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, + qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial, &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* sets facet->visitid */ - fprintf (fp, "%d\n", numpoints); + 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); + 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); + qh_point_add(vertex_points, vertex->point, vertex); FORALLfacet_(facetlist) { FOREACHpoint_(facet->coplanarset) - qh_point_add (coplanar_points, point, facet); + qh_point_add(coplanar_points, point, facet); } FOREACHfacet_(facets) { FOREACHpoint_(facet->coplanarset) - qh_point_add (coplanar_points, point, facet); + qh_point_add(coplanar_points, point, facet); } FOREACHvertex_i_(vertex_points) { - if (vertex) { - numneighbors= qh_setsize (vertex->neighbors); - fprintf (fp, "%d", numneighbors); + if (vertex) { + numneighbors= qh_setsize(vertex->neighbors); + qh_fprintf(fp, 9249, "%d", numneighbors); if (qh hull_dim == 3) - qh_order_vertexneighbors (vertex); + qh_order_vertexneighbors(vertex); else if (qh hull_dim >= 4) - qsort (SETaddr_(vertex->neighbors, facetT), numneighbors, - sizeof (facetT *), qh_compare_facetvisit); - FOREACHneighbor_(vertex) - fprintf (fp, " %d", - neighbor->visitid ? neighbor->visitid - 1 : - neighbor->id); - fprintf (fp, "\n"); + qsort(SETaddr_(vertex->neighbors, facetT), 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))) - fprintf (fp, "1 %d\n", - facet->visitid ? facet->visitid - 1 : - facet->id); + qh_fprintf(fp, 9252, "1 %d\n", + facet->visitid ? facet->visitid - 1 : 0 - facet->id); else - fprintf (fp, "0\n"); + qh_fprintf(fp, 9253, "0\n"); } - qh_settempfree (&coplanar_points); - qh_settempfree (&vertex_points); - qh_settempfree (&vertices); + 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 @@ -3469,12 +3374,12 @@ void qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printa qh_printvdiagram() notes: - if 'o', + if 'o', prints a line for each point except "at-infinity" - if all facets are upperdelaunay, + if all facets are upperdelaunay, reverses lower and upper hull */ -void qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) { +void qh_printvoronoi(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) { int k, numcenters, numvertices= 0, numneighbors, numinf, vid=1, vertex_i, vertex_n; facetT *facet, **facetp, *neighbor, **neighborp; setT *vertices; @@ -3482,49 +3387,49 @@ void qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boo boolT islower; unsigned int numfacets= (unsigned int) qh num_facets; - vertices= qh_markvoronoi (facetlist, facets, printall, &islower, &numcenters); + 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; + numinf= 1; else if (neighbor->visitid < numfacets) numneighbors++; } if (numinf && !numneighbors) { - SETelem_(vertices, vertex_i)= NULL; - numvertices--; + SETelem_(vertices, vertex_i)= NULL; + numvertices--; } } } - if (format == qh_PRINTgeom) - fprintf (fp, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n", + if (format == qh_PRINTgeom) + qh_fprintf(fp, 9254, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n", numcenters, numvertices); else - fprintf (fp, "%d\n%d %d 1\n", qh hull_dim-1, numcenters, qh_setsize(vertices)); + 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--; ) - fprintf (fp, qh_REAL_1, 0.0); - fprintf (fp, " 0 # infinity not used\n"); + 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--; ) - fprintf (fp, qh_REAL_1, qh_INFINITE); - fprintf (fp, "\n"); + 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) - fprintf (fp, "# %d f%d\n", vid++, facet->id); - qh_printcenter (fp, format, NULL, facet); + 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) - fprintf (fp, "# %d f%d\n", vid++, facet->id); - qh_printcenter (fp, format, NULL, facet); + qh_fprintf(fp, 9261, "# %d f%d\n", vid++, facet->id); + qh_printcenter(fp, format, NULL, facet); } } FOREACHvertex_i_(vertices) { @@ -3534,117 +3439,121 @@ void qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boo if (qh hull_dim == 3) qh_order_vertexneighbors(vertex); else if (qh hull_dim >= 4) - qsort (SETaddr_(vertex->neighbors, vertexT), - qh_setsize (vertex->neighbors), - sizeof (facetT *), qh_compare_facetvisit); + qsort(SETaddr_(vertex->neighbors, vertexT), + qh_setsize(vertex->neighbors), + sizeof(facetT *), qh_compare_facetvisit); FOREACHneighbor_(vertex) { if (neighbor->visitid == 0) - numinf= 1; - else if (neighbor->visitid < numfacets) + numinf= 1; + else if (neighbor->visitid < numfacets) numneighbors++; } } if (format == qh_PRINTgeom) { if (vertex) { - fprintf (fp, "%d", numneighbors); - if (vertex) { - FOREACHneighbor_(vertex) { - if (neighbor->visitid && neighbor->visitid < numfacets) - fprintf (fp, " %d", neighbor->visitid); - } - } - fprintf (fp, " # p%d (v%d)\n", vertex_i, vertex->id); + qh_fprintf(fp, 9262, "%d", numneighbors); + if (vertex) { + 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 - fprintf (fp, " # p%d is coplanar or isolated\n", vertex_i); + qh_fprintf(fp, 9265, " # p%d is coplanar or isolated\n", vertex_i); }else { if (numinf) - numneighbors++; - fprintf (fp, "%d", numneighbors); + numneighbors++; + qh_fprintf(fp, 9266, "%d", numneighbors); if (vertex) { FOREACHneighbor_(vertex) { - if (neighbor->visitid == 0) { - if (numinf) { - numinf= 0; - fprintf (fp, " %d", neighbor->visitid); - } - }else if (neighbor->visitid < numfacets) - fprintf (fp, " %d", neighbor->visitid); - } + 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); + } } - fprintf (fp, "\n"); + qh_fprintf(fp, 9269, "\n"); } } if (format == qh_PRINTgeom) - fprintf (fp, "}\n"); - qh_settempfree (&vertices); + 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) { +void qh_printvnorm(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) { pointT *normal; realT offset; int k; - - normal= qh_detvnorm (vertex, vertexA, centers, &offset); - fprintf (fp, "%d %d %d ", - 2+qh hull_dim, qh_pointid (vertex->point), qh_pointid (vertexA->point)); - for (k= 0; k< qh hull_dim-1; k++) - fprintf (fp, qh_REAL_1, normal[k]); - fprintf (fp, qh_REAL_1, offset); - fprintf (fp, "\n"); + + 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) { +void qh_printvridge(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) { facetT *facet, **facetp; - fprintf (fp, "%d %d %d", qh_setsize (centers)+2, - qh_pointid (vertex->point), qh_pointid (vertexA->point)); - FOREACHfacet_(centers) - fprintf (fp, " %d", facet->visitid); - fprintf (fp, "\n"); + 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++) { + for (k=0, i=0; k < qh hull_dim; k++) { if (qh hull_dim == 4) { if (k != qh DROPdim) destination[i++]= source[k]; @@ -3659,7 +3568,7 @@ void qh_projectdim3 (pointT *source, pointT *destination) { /*-<a href="qh-io.htm#TOC" >-------------------------------</a><a name="readfeasible">-</a> - + qh_readfeasible( dim, remainder ) read feasible point from remainder string and qh.fin @@ -3674,20 +3583,20 @@ void qh_projectdim3 (pointT *source, pointT *destination) { see: qh_setfeasible */ -int qh_readfeasible (int dim, char *remainder) { +int qh_readfeasible(int dim, char *remainder) { boolT isfirst= True; int linecount= 0, tokcount= 0; char *s, *t, firstline[qh_MAXfirst+1]; coordT *coords, value; if (!qh HALFspace) { - fprintf (qh ferr, "qhull input error: feasible point (dim 1 coords) is only valid for halfspace intersection\n"); - qh_errexit (qh_ERRinput, NULL, NULL); - } + 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) - fprintf (qh ferr, "qhull input warning: feasible point (dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n"); - if (!(qh feasible_point= (coordT*)malloc (dim* sizeof(coordT)))) { - fprintf(qh ferr, "qhull error: insufficient memory for feasible point\n"); + qh_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; @@ -3699,33 +3608,33 @@ int qh_readfeasible (int dim, char *remainder) { while (*s) { while (isspace(*s)) s++; - value= qh_strtod (s, &t); + value= qh_strtod(s, &t); if (s == t) break; s= t; *(coords++)= value; if (++tokcount == dim) { - while (isspace (*s)) + while (isspace(*s)) s++; - qh_strtod (s, &t); + qh_strtod(s, &t); if (s != t) { - fprintf (qh ferr, "qhull input error: coordinates for feasible point do not finish out the line: %s\n", + 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); + qh_errexit(qh_ERRinput, NULL, NULL); } return linecount; } } } - fprintf (qh ferr, "qhull input error: only %d coordinates. Could not read %d-d feasible point.\n", + 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); + 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 @@ -3759,7 +3668,7 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { coordT *points, *coords, *infinity= NULL; realT paraboloid, maxboloid= -REALmax, value; realT *coordp= NULL, *offsetp= NULL, *normalp= NULL; - char *s, *t, firstline[qh_MAXfirst+1]; + 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; @@ -3770,26 +3679,26 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { while ((s= fgets(firstline, qh_MAXfirst, qh fin))) { linecount++; if (qh HALFspace && linecount == 1 && isdigit(*s)) { - dimfeasible= qh_strtol (s, &s); - while (isspace(*s)) + dimfeasible= qh_strtol(s, &s); + while (isspace(*s)) s++; - if (qh_strtol (s, &s) == 1) - linecount += qh_readfeasible (dimfeasible, s); + if (qh_strtol(s, &s) == 1) + linecount += qh_readfeasible(dimfeasible, s); else dimfeasible= 0; - }else if (!memcmp (firstline, "begin", 5) || !memcmp (firstline, "BEGIN", 5)) + }else if (!memcmp(firstline, "begin", 5) || !memcmp(firstline, "BEGIN", 5)) break; else if (!*qh rbox_command) - strncat(qh rbox_command, s, sizeof (qh rbox_command)-1); + strncat(qh rbox_command, s, sizeof(qh rbox_command)-1); } if (!s) { - fprintf (qh ferr, "qhull input error: missing \"begin\" for cdd-formated input\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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))) { + while (!numinput && (s= fgets(firstline, qh_MAXfirst, qh fin))) { linecount++; - if (!memcmp (s, "begin", 5) || !memcmp (s, "BEGIN", 5)) + if (!memcmp(s, "begin", 5) || !memcmp(s, "BEGIN", 5)) wasbegin= True; while (*s) { while (isspace(*s)) @@ -3798,36 +3707,36 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { break; if (!isdigit(*s)) { if (!*qh rbox_command) { - strncat(qh rbox_command, s, sizeof (qh rbox_command)-1); - firsttext= linecount; + strncat(qh rbox_command, s, sizeof(qh rbox_command)-1); + firsttext= linecount; } break; } - if (!diminput) - diminput= qh_strtol (s, &s); + if (!diminput) + diminput= qh_strtol(s, &s); else { - numinput= qh_strtol (s, &s); + numinput= qh_strtol(s, &s); if (numinput == 1 && diminput >= 2 && qh HALFspace && !qh CDDinput) { - linecount += qh_readfeasible (diminput, s); /* checks if ok */ + linecount += qh_readfeasible(diminput, s); /* checks if ok */ dimfeasible= diminput; diminput= numinput= 0; - }else + }else break; } } } if (!s) { - fprintf(qh ferr, "qhull input error: short input file. Did not find dimension and number of points\n"); + 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 */ + tempi= diminput; /* exchange dim and n, e.g., for cdd input format */ diminput= numinput; numinput= tempi; } if (diminput < 2) { - fprintf(qh ferr,"qhull input error: dimension %d (first number) should be at least 2\n", - diminput); + qh_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) { @@ -3843,20 +3752,20 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { *dimension= diminput - 1; *numpoints= numinput; if (diminput < 3) { - fprintf(qh ferr,"qhull input error: dimension %d (first number, includes offset) should be at least 3 for halfspaces\n", - diminput); + qh_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) { - fprintf(qh ferr,"qhull input error: dimension %d of feasible point is not one less than dimension %d for halfspaces\n", + 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 + qh_setfeasible(*dimension); }else { - if (qh CDDinput) + if (qh CDDinput) *dimension= diminput-1; else *dimension= diminput; @@ -3864,7 +3773,7 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { } qh normal_size= *dimension * sizeof(coordT); /* for tracing with qh_printpoint */ if (qh HALFspace) { - qh half_space= coordp= (coordT*) malloc (qh normal_size + sizeof(coordT)); + qh half_space= coordp= (coordT*) qh_malloc(qh normal_size + sizeof(coordT)); if (qh CDDinput) { offsetp= qh half_space; normalp= offsetp + 1; @@ -3872,16 +3781,16 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { normalp= qh half_space; offsetp= normalp + *dimension; } - } + } qh maxline= diminput * (qh_REALdigits + 5); maximize_(qh maxline, 500); - qh line= (char*)malloc ((qh maxline+1) * sizeof (char)); + qh line= (char*)qh_malloc((qh maxline+1) * sizeof(char)); *ismalloc= True; /* use malloc since memory not setup */ - coords= points= qh temp_malloc= - (coordT*)malloc((*numpoints)*(*dimension)*sizeof(coordT)); + coords= points= qh temp_malloc= + (coordT*)qh_malloc((*numpoints)*(*dimension)*sizeof(coordT)); if (!coords || !qh line || (qh HALFspace && !qh half_space)) { - fprintf(qh ferr, "qhull error: insufficient memory to read %d points\n", - numinput); + qh_fprintf(qh ferr, 6076, "qhull error: insufficient memory to read %d points\n", + numinput); qh_errexit(qh_ERRmem, NULL, NULL); } if (isdelaunay && qh ATinfinity) { @@ -3895,56 +3804,56 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { if (!isfirst) { linecount++; if (*s == 'e' || *s == 'E') { - if (!memcmp (s, "end", 3) || !memcmp (s, "END", 3)) { - if (qh CDDinput ) - break; - else if (wasbegin) - fprintf (qh ferr, "qhull input warning: the input appears to be in cdd format. If so, use 'Fd'\n"); - } + if (!memcmp(s, "end", 3) || !memcmp(s, "END", 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); + 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) + 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; + firstpoint= linecount; s= t; if (++tokcount > maxcount) continue; if (qh HALFspace) { - if (qh CDDinput) - *(coordp++)= -value; /* both coefficients and offset */ - else - *(coordp++)= value; + if (qh CDDinput) + *(coordp++)= -value; /* both coefficients and offset */ + else + *(coordp++)= value; }else { *(coords++)= value; if (qh CDDinput && !coordcount) { if (value != 1.0) { - fprintf (qh ferr, "qhull input error: for cdd format, point at line %d does not start with '1'\n", + 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); + 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; - } - } + paraboloid += value * value; + if (qh ATinfinity) { + if (qh CDDinput) + infinity[coordcount-1] += value; + else + infinity[coordcount] += value; + } + } } if (++coordcount == diminput) { coordcount= 0; @@ -3953,49 +3862,49 @@ coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) { maximize_(maxboloid, paraboloid); paraboloid= 0.0; }else if (qh HALFspace) { - if (!qh_sethalfspace (*dimension, coords, &coords, normalp, offsetp, qh feasible_point)) { - fprintf (qh ferr, "The halfspace was on line %d\n", linecount); - if (wasbegin) - fprintf (qh ferr, "The input appears to be in cdd format. If so, you should use option 'Fd'\n"); - qh_errexit (qh_ERRinput, NULL, NULL); - } + 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) { - fprintf(qh ferr, "qhull input error: line %d contained more than %d characters\n", - linecount, (int) (s - qh line)); + 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); - fprintf(qh ferr,"\ + 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) - fprintf(qh ferr, ", line %d is the first comment", firsttext); + qh_fprintf(qh ferr, 8051, ", line %d is the first comment", firsttext); if (firstshort) - fprintf(qh ferr, ", line %d is the first short\nline", firstshort); + qh_fprintf(qh ferr, 8052, ", line %d is the first short\nline", firstshort); if (firstlong) - fprintf(qh ferr, ", line %d is the first long line", firstlong); - fprintf(qh ferr, ". Continue with %d points.\n", newnum); + 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); + infinity[k] -= *(--coords); *numpoints= newnum+1; }else { coords -= tokcount % diminput; @@ -4008,15 +3917,15 @@ qhull warning: instead of %d %d-dimensional points, input contains\n\ if (coords == infinity) coords += (*dimension) -1; else { - for (k= 0; k < (*dimension) -1; k++) - *(coords++)= infinity[k]; + for (k=0; k < (*dimension) -1; k++) + *(coords++)= infinity[k]; } *(coords++)= maxboloid * 1.1; } if (qh rbox_command[0]) { qh rbox_command[strlen(qh rbox_command)-1]= '\0'; - if (!strcmp (qh rbox_command, "./rbox D4")) - fprintf (qh ferr, "\n\ + 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\ @@ -4025,22 +3934,22 @@ please send mail to qhull_bug@qhull.org.\n\ \n\ Type 'qhull' for a short list of options.\n"); } - free (qh line); + qh_free(qh line); qh line= NULL; if (qh half_space) { - free (qh half_space); + qh_free(qh half_space); qh half_space= NULL; } qh temp_malloc= NULL; - trace1((qh ferr,"qh_readpoints: read in %d %d-dimensional points\n", - numinput, diminput)); + 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 @@ -4048,26 +3957,26 @@ Type 'qhull' for a short list of options.\n"); "n,n,n" already checked by qh_initflags() see qh_readfeasible() */ -void qh_setfeasible (int dim) { +void qh_setfeasible(int dim) { int tokcount= 0; char *s; coordT *coords, value; if (!(s= qh feasible_string)) { - fprintf(qh ferr, "\ + 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); + qh_errexit(qh_ERRinput, NULL, NULL); } - if (!(qh feasible_point= (pointT*)malloc (dim* sizeof(coordT)))) { - fprintf(qh ferr, "qhull error: insufficient memory for 'Hn,n,n'\n"); + 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); + value= qh_strtod(s, &s); if (++tokcount > dim) { - fprintf (qh ferr, "qhull input warning: more coordinates for 'H%s' than dimension %d\n", + qh_fprintf(qh ferr, 7059, "qhull input warning: more coordinates for 'H%s' than dimension %d\n", qh feasible_string, dim); break; } @@ -4075,15 +3984,15 @@ Either prepend the input with 1 point or use 'Hn,n,n'. See manual.\n"); if (*s) s++; } - while (++tokcount <= dim) + 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 + returns 'True' if this facet is not to be printed notes: based on the user provided slice thresholds and 'good' specifications @@ -4096,13 +4005,51 @@ boolT qh_skipfacet(facetT *facet) { return !qh PRINTgood; FOREACHneighbor_(facet) { if (neighbor->good) - return False; + return False; } return True; }else if (qh PRINTgood) return !facet->good; else if (!facet->normal) return True; - return (!qh_inthresholds (facet->normal, NULL)); + 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; + 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/io.h b/src/io.h index 77bb61d..2ed4b1d 100644 --- a/src/io.h +++ b/src/io.h @@ -4,14 +4,18 @@ io.h declarations of Input/Output functions - see README, qhull.h and io.c + see README, qhulllib.h and io.c - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/io.h#21 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ #ifndef qhDEFio #define qhDEFio 1 +#include "qhulllib.h" + /*============ constants and flags ==================*/ /*-<a href="qh-io.htm#TOC" @@ -73,42 +77,43 @@ typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT * /*============== -prototypes in alphabetical order =========*/ -void dfacet( unsigned id); -void dvertex( unsigned id); +void dfacet(unsigned id); +void dvertex(unsigned id); int qh_compare_facetarea(const void *p1, const void *p2); int qh_compare_facetmerge(const void *p1, const void *p2); int qh_compare_facetvisit(const void *p1, const void *p2); int qh_compare_vertexpoint(const void *p1, const void *p2); /* not used */ - -void qh_countfacets (facetT *facetlist, setT *facets, boolT printall, +void qh_copyfilename(char *filename, int size, char* source, int length); +void qh_countfacets(facetT *facetlist, setT *facets, boolT printall, int *numfacetsp, int *numsimplicialp, int *totneighborsp, int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp); -pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp); -setT *qh_detvridge (vertexT *vertex); +pointT *qh_detvnorm(vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp); +setT *qh_detvridge(vertexT *vertex); setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex); -int qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder); -int qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder); +int qh_eachvoronoi(FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder); +int qh_eachvoronoi_all(FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder); void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist); -setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets); -void qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane); -void qh_markkeep (facetT *facetlist); -setT *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp); +setT *qh_facetvertices(facetT *facetlist, setT *facets, boolT allfacets); +void qh_geomplanes(facetT *facet, realT *outerplane, realT *innerplane); +void qh_markkeep(facetT *facetlist); +setT *qh_markvoronoi(facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp); void qh_order_vertexneighbors(vertexT *vertex); +void qh_prepare_output(void); void qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall); -void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); -void qh_printcenter (FILE *fp, int format, char *string, facetT *facet); -void qh_printcentrum (FILE *fp, facetT *facet, realT radius); -void qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); -void qh_printend4geom (FILE *fp, facetT *facet, int *num, boolT printall); -void qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall); -void qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall); -void qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall); +void qh_printbegin(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); +void qh_printcenter(FILE *fp, int format, char *string, facetT *facet); +void qh_printcentrum(FILE *fp, facetT *facet, realT radius); +void qh_printend(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); +void qh_printend4geom(FILE *fp, facetT *facet, int *num, boolT printall); +void qh_printextremes(FILE *fp, facetT *facetlist, setT *facets, int printall); +void qh_printextremes_2d(FILE *fp, facetT *facetlist, setT *facets, int printall); +void qh_printextremes_d(FILE *fp, facetT *facetlist, setT *facets, int printall); void qh_printfacet(FILE *fp, facetT *facet); void qh_printfacet2math(FILE *fp, facetT *facet, int format, int notfirst); void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]); void qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2, facetT *facet, realT offset, realT color[3]); -void qh_printfacet3math (FILE *fp, facetT *facet, int format, int notfirst); +void qh_printfacet3math(FILE *fp, facetT *facet, int format, int notfirst); void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]); void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]); void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]); @@ -120,35 +125,35 @@ void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format); void qh_printfacetheader(FILE *fp, facetT *facet); void qh_printfacetridges(FILE *fp, facetT *facet); void qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); -void qh_printhelp_degenerate(FILE *fp); -void qh_printhelp_singular(FILE *fp); void qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2, setT *vertices, realT color[3]); -void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall); -void qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]); +void qh_printneighborhood(FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall); +void qh_printline3geom(FILE *fp, pointT *pointA, pointT *pointB, realT color[3]); void qh_printpoint(FILE *fp, char *string, pointT *point); void qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id); void qh_printpoint3 (FILE *fp, pointT *point); -void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall); -void qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]); +void qh_printpoints_out(FILE *fp, facetT *facetlist, setT *facets, int printall); +void qh_printpointvect(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]); void qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius); void qh_printridge(FILE *fp, ridgeT *ridge); void qh_printspheres(FILE *fp, setT *vertices, realT radius); -void qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); +void qh_printvdiagram(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); int qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder); void qh_printvertex(FILE *fp, vertexT *vertex); -void qh_printvertexlist (FILE *fp, char* string, facetT *facetlist, +void qh_printvertexlist(FILE *fp, char* string, facetT *facetlist, setT *facets, boolT printall); -void qh_printvertices (FILE *fp, char* string, setT *vertices); -void qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall); -void qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); -void qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded); -void qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded); +void qh_printvertices(FILE *fp, char* string, setT *vertices); +void qh_printvneighbors(FILE *fp, facetT* facetlist, setT *facets, boolT printall); +void qh_printvoronoi(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall); +void qh_printvnorm(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded); +void qh_printvridge(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded); void qh_produce_output(void); +void qh_produce_output2(void); void qh_projectdim3 (pointT *source, pointT *destination); -int qh_readfeasible (int dim, char *remainder); +int qh_readfeasible(int dim, char *remainder); coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc); -void qh_setfeasible (int dim); +void qh_setfeasible(int dim); boolT qh_skipfacet(facetT *facet); +char *qh_skipfilename(char *filename); #endif /* qhDEFio */ diff --git a/src/mem.c b/src/mem.c index 5d2f18b..4bca682 100644 --- a/src/mem.c +++ b/src/mem.c @@ -8,17 +8,17 @@ To initialize memory: - qh_meminit (stderr); - qh_meminitbuffers (qh IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf); + qh_meminit(stderr); + qh_meminitbuffers(qh IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf); qh_memsize(sizeof(facetT)); qh_memsize(sizeof(facetT)); ... qh_memsetup(); To free up all memory buffers: - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); - if qh_NOmem, + if qh_NOmem, malloc/free is used instead of mem.c notes: @@ -29,18 +29,29 @@ qh-mem.htm and mem.h global.c (qh_initbuffers) for an example of using mem.c - copyright (c) 1993-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/mem.c#26 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ +#include "mem.h" +#include <string.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include "mem.h" -#ifndef qhDEFqhull +#ifndef qhDEFqhulllib 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 : 4224) /* nonstandard extension used : formal parameter 'errcode' was previously defined as a type. [errcode was replaced by errno_t] */ +#pragma warning( disable : 4706) /* assignment within conditional function */ +#endif void qh_errexit(int exitcode, facetT *, ridgeT *); +void qh_exit(int errcode); +void qh_fprintf(FILE *fp, int msgcode, char *fmt, ... ); +void qh_free(void *mem); +void *qh_malloc(unsigned int size); #endif /*============ -global data structure ============== @@ -94,32 +105,39 @@ static int qh_intcompare(const void *i, const void *j) { allocate new allocation buffer if necessary allocate object from allocation buffer else - allocate object with malloc() + allocate object with qh_malloc() in user.c */ void *qh_memalloc(int insize) { void **freelistp, *newbuffer; - int index, size; + int index, size, n; int outsize, bufsize; void *object; if ((unsigned) insize <= (unsigned) qhmem.LASTsize) { index= qhmem.indextable[insize]; + outsize= qhmem.sizetable[index]; + qhmem.totshort += outsize; freelistp= qhmem.freelists+index; if ((object= *freelistp)) { qhmem.cntquick++; + qhmem.totfree -= outsize; *freelistp= *((void **)*freelistp); /* replace freelist with next object */ - return (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 { - outsize= qhmem.sizetable[index]; qhmem.cntshort++; if (outsize > qhmem .freesize) { + qhmem .totdropped += qhmem .freesize; if (!qhmem.curbuffer) bufsize= qhmem.BUFinit; else bufsize= qhmem.BUFsize; - qhmem.totshort += bufsize; - if (!(newbuffer= malloc(bufsize))) { - fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n"); + if (!(newbuffer= qh_malloc(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 @@ -128,38 +146,50 @@ void *qh_memalloc(int insize) { 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) { - fprintf (qhmem.ferr, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n"); + 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 .curlong++; qhmem .totlong += outsize; if (qhmem.maxlong < qhmem.totlong) qhmem.maxlong= qhmem.totlong; - if (!(object= malloc(outsize))) { - fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n"); + if (!(object= qh_malloc(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) - fprintf (qhmem.ferr, "qh_memalloc long: %d bytes at %p\n", outsize, object); + 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); + return(object); } /* memalloc */ /*-<a href="qh-mem.htm#TOC" >--------------------------------</a><a name="memfree">-</a> - qh_memfree( object, size ) + qh_memfree( object, insize ) free up an object of size bytes size is insize from qh_memalloc @@ -172,24 +202,34 @@ void *qh_memalloc(int insize) { if size <= qhmem.LASTsize append object to corresponding freelist else - call free(object) + call qh_free(object) */ -void qh_memfree(void *object, int size) { +void qh_memfree(void *object, int insize) { void **freelistp; + int index, outsize; if (!object) return; - if (size <= qhmem.LASTsize) { + if (insize <= qhmem.LASTsize) { qhmem .freeshort++; - freelistp= qhmem.freelists + qhmem.indextable[size]; + index= qhmem.indextable[insize]; + outsize= qhmem.sizetable[index]; + qhmem .totfree += outsize; + qhmem .totshort -= outsize; + freelistp= qhmem.freelists + index; *((void **)object)= *freelistp; *freelistp= object; +#ifdef qh_TRACEshort + index= 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, index, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort); +#endif }else { qhmem .freelong++; - qhmem .totlong -= size; - free (object); + qhmem .totlong -= insize; + qh_free(object); if (qhmem.IStracing >= 5) - fprintf (qhmem.ferr, "qh_memfree long: %d bytes at %p\n", size, object); + 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 */ @@ -202,22 +242,26 @@ void qh_memfree(void *object, int size) { 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 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) { + for (buffer= qhmem.curbuffer; buffer; buffer= nextbuffer) { nextbuffer= *((void **) buffer); - free(buffer); + qh_free(buffer); } qhmem.curbuffer= NULL; if (qhmem .LASTsize) { - free (qhmem .indextable); - free (qhmem .freelists); - free (qhmem .sizetable); + 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 */ @@ -231,13 +275,17 @@ void qh_memfreeshort (int *curlong, int *totlong) { qh_meminit( ferr ) initialize qhmem and test sizeof( void*) */ -void qh_meminit (FILE *ferr) { +void qh_meminit(FILE *ferr) { memset((char *)&qhmem, 0, sizeof qhmem); /* every field is 0, FALSE, NULL */ qhmem.ferr= ferr; if (sizeof(void*) < sizeof(int)) { - fprintf (ferr, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int). qset.c will not work\n"); - exit (1); /* can not use qh_errexit() */ + qh_fprintf(ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int). qset.c will not work\n"); + qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */ + } + if (sizeof(void*) > sizeof(ptr_intT)) { + qh_fprintf(ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) > sizeof(ptr_intT). Change ptr_intT in mem.h to 'long long'\n"); + qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */ } } /* meminit */ @@ -252,7 +300,7 @@ void qh_meminit (FILE *ferr) { 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) { +void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) { qhmem.IStracing= tracelevel; qhmem.NUMsizes= numsizes; @@ -260,17 +308,17 @@ void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize qhmem.BUFinit= bufinit; qhmem.ALIGNmask= alignment-1; if (qhmem.ALIGNmask & ~qhmem.ALIGNmask) { - fprintf (qhmem.ferr, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + 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 (numsizes, sizeof(int)); - qhmem.freelists= (void **) calloc (numsizes, sizeof(void *)); + qhmem.sizetable= (int *) calloc(numsizes, sizeof(int)); + qhmem.freelists= (void **) calloc(numsizes, sizeof(void *)); if (!qhmem.sizetable || !qhmem.freelists) { - fprintf(qhmem.ferr, "qhull error (qh_meminit): insufficient memory\n"); - qh_errexit (qhmem_ERRmem, NULL, NULL); + qh_fprintf(qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n"); + qh_errexit(qhmem_ERRmem, NULL, NULL); } if (qhmem.IStracing >= 1) - fprintf (qhmem.ferr, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment); + qh_fprintf(qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment); } /* meminitbuffers */ /*-<a href="qh-mem.htm#TOC" @@ -279,24 +327,24 @@ void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize qh_memsetup() set up memory after running memsize() */ -void qh_memsetup (void) { +void qh_memsetup(void) { int k,i; qsort(qhmem.sizetable, qhmem.TABLEsize, sizeof(int), qh_intcompare); qhmem.LASTsize= qhmem.sizetable[qhmem.TABLEsize-1]; if (qhmem .LASTsize >= qhmem .BUFsize || qhmem.LASTsize >= qhmem .BUFinit) { - fprintf (qhmem.ferr, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n", + 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 *)malloc((qhmem.LASTsize+1) * sizeof(int)))) { - fprintf(qhmem.ferr, "qhull error (qh_memsetup): insufficient memory\n"); + 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--; ) + for (k=qhmem.LASTsize+1; k--; ) qhmem.indextable[k]= k; i= 0; - for(k= 0; k <= qhmem.LASTsize; k++) { + for (k=0; k <= qhmem.LASTsize; k++) { if (qhmem.indextable[k] <= qhmem.sizetable[i]) qhmem.indextable[k]= i; else @@ -314,18 +362,18 @@ void qh_memsize(int size) { int k; if (qhmem .LASTsize) { - fprintf (qhmem .ferr, "qhull error (qh_memsize): called after qhmem_setup\n"); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + 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--; ) { + for (k=qhmem.TABLEsize; k--; ) { if (qhmem.sizetable[k] == size) return; } if (qhmem.TABLEsize < qhmem.NUMsizes) qhmem.sizetable[qhmem.TABLEsize++]= size; else - fprintf(qhmem.ferr, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes); + qh_fprintf(qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes); } /* memsize */ @@ -335,10 +383,9 @@ void qh_memsize(int size) { qh_memstatistics( fp ) print out memory statistics - notes: - does not account for wasted memory at the end of each block + Verifies that qhmem.totfree == sum of freelists */ -void qh_memstatistics (FILE *fp) { +void qh_memstatistics(FILE *fp) { int i, count, totfree= 0; void *object; @@ -348,7 +395,11 @@ void qh_memstatistics (FILE *fp) { count++; totfree += qhmem.sizetable[i] * count; } - fprintf (fp, "\nmemory statistics:\n\ + 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\ @@ -356,27 +407,30 @@ void qh_memstatistics (FILE *fp) { %7d long frees\n\ %7d bytes of short memory in use\n\ %7d bytes of short memory in freelists\n\ -%7d bytes of long memory allocated (except for input)\n\ +%7d bytes of 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 per memory buffer (initially %d bytes)\n", - qhmem .cntquick, qhmem.cntshort, qhmem.cntlong, - qhmem .freeshort, qhmem.freelong, - qhmem .totshort - qhmem .freesize - totfree, - totfree, +%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 .BUFsize, qhmem .BUFinit); + qhmem .totbuffer, qhmem .BUFsize, qhmem .BUFinit); if (qhmem.cntlarger) { - fprintf (fp, "%7d calls to qh_setlarger\n%7.2g average copy size\n", + qh_fprintf(fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n", qhmem.cntlarger, ((float) qhmem.totlarger)/ qhmem.cntlarger); - fprintf (fp, " freelists (bytes->count):"); + 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++; - fprintf (fp, " %d->%d", qhmem.sizetable[i], count); + qh_fprintf(fp, 9281, " %d->%d", qhmem.sizetable[i], count); } - fprintf (fp, "\n\n"); + qh_fprintf(fp, 9282, "\n\n"); } /* memstatistics */ @@ -387,55 +441,59 @@ void qh_memstatistics (FILE *fp) { turn off quick-fit memory allocation notes: - uses malloc() and free() instead + uses qh_malloc() and qh_free() instead */ #else /* qh_NOmem */ void *qh_memalloc(int insize) { void *object; - if (!(object= malloc(insize))) { - fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n"); + if (!(object= qh_malloc(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) - fprintf (qhmem.ferr, "qh_memalloc long: %d bytes at %p\n", insize, object); + 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 size) { +void qh_memfree(void *object, int insize) { if (!object) return; - free (object); + qh_free(object); + qhmem .freelong++; + qhmem .totlong -= insize; if (qhmem.IStracing >= 5) - fprintf (qhmem.ferr, "qh_memfree long: %d bytes at %p\n", size, object); + 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) { - +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 */ - *curlong= 0; - *totlong= 0; } -void qh_meminit (FILE *ferr) { +void qh_meminit(FILE *ferr) { memset((char *)&qhmem, 0, sizeof qhmem); /* every field is 0, FALSE, NULL */ qhmem.ferr= ferr; if (sizeof(void*) < sizeof(int)) { - fprintf (ferr, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int). qset.c will not work\n"); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_fprintf(ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int). qset.c will not work\n"); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } } -void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) { +void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) { qhmem.IStracing= tracelevel; - } -void qh_memsetup (void) { +void qh_memsetup(void) { } @@ -443,8 +501,38 @@ void qh_memsize(int size) { } -void qh_memstatistics (FILE *fp) { +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 (UsingQhullLib.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/mem.h b/src/mem.h index fb141f0..a0e6741 100644 --- a/src/mem.h +++ b/src/mem.h @@ -7,15 +7,19 @@ 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 + qh_errexit(qhmem_ERRmem, NULL, NULL) if insufficient memory and - qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise + qh_errexit(qhmem_ERRqhull, NULL, NULL) otherwise - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/mem.h#21 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ #ifndef qhDEFmem -#define qhDEFmem +#define qhDEFmem 1 + +#include <stdio.h> /*-<a href="qh-mem.htm#TOC" >-------------------------------</a><a name="NOmem">-</a> @@ -32,6 +36,15 @@ #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 @@ -46,20 +59,24 @@ see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment */ -#define qhmem_ERRmem 4 /* matches qh_ERRmem in qhull.h */ -#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in qhull.h */ +#define qhmem_ERRmem 4 /* matches qh_ERRmem in qhulllib.h */ +#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in qhulllib.h */ /*-<a href="qh-mem.htm#TOC" >--------------------------------</a><a name="ptr_intT">-</a> ptr_intT - for casting a void* to an integer-type + 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() checks that 'long' holds a 'void*' + qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*' + ptr_intT is not defined as 'long long' for portability to older compilers + size_t is typically an unsigned int */ -typedef unsigned long ptr_intT; +typedef long ptr_intT; /*-<a href="qh-mem.htm#TOC" >--------------------------------</a><a name="qhmemT">-</a> @@ -94,20 +111,23 @@ struct qhmemT { /* global memory management variables */ int *indextable; /* size->index table */ void *curbuffer; /* current buffer, linked by offset 0 */ void *freemem; /* free memory in curbuffer */ - int freesize; /* size of free memory in bytes */ + int freesize; /* size of freemem in bytes */ void *tempstack; /* stack of temporary memory, managed by users */ - FILE *ferr; /* file for reporting errors */ + FILE *ferr; /* file for reporting errors, only user is qh_fprintf() */ int IStracing; /* =5 if tracing memory allocations */ int cntquick; /* count of quick allocations */ - /* remove statistics doesn't effect speed */ + /* Note: removing statistics doesn't effect speed */ int cntshort; /* count of short allocations */ int cntlong; /* count of long allocations */ - int curlong; /* current count of inuse, long allocations */ int freeshort; /* count of short memfrees */ int freelong; /* count of long memfrees */ - int totshort; /* total size of short allocations */ - int totlong; /* total size of long allocations */ - int maxlong; /* maximum totlong */ + int 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 */ }; @@ -118,43 +138,55 @@ struct qhmemT { /* global memory management variables */ /*-<a href="qh-mem.htm#TOC" >--------------------------------</a><a name="memalloc_">-</a> - qh_memalloc_(size, object, type) + qh_memalloc_(insize, object, type) returns object of size bytes assumes size<=qhmem.LASTsize and void **freelistp is a temp */ -#ifdef qh_NOmem -#define qh_memalloc_(size, freelistp, object, type) {\ - object= (type*)qh_memalloc (size); } +#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_(size, freelistp, object, type) {\ - freelistp= qhmem.freelists + qhmem.indextable[size];\ +#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 (size);} + }else object= (type*)qh_memalloc(insize);} #endif /*-<a href="qh-mem.htm#TOC" >--------------------------------</a><a name="memfree_">-</a> - qh_memfree_(object, size) + qh_memfree_(object, insize) free up an object notes: object may be NULL assumes size<=qhmem.LASTsize and void **freelistp is a temp */ -#ifdef qh_NOmem -#define qh_memfree_(object, size, freelistp) {\ - qh_memfree (object, size); } +#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, size, freelistp) {\ +#define qh_memfree_(object, insize, freelistp) {\ if (object) { \ qhmem .freeshort++;\ - freelistp= qhmem.freelists + qhmem.indextable[size];\ + 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 @@ -162,13 +194,14 @@ struct qhmemT { /* global memory management variables */ /*=============== prototypes in alphabetical order ============*/ void *qh_memalloc(int insize); -void qh_memfree (void *object, int size); -void qh_memfreeshort (int *curlong, int *totlong); -void qh_meminit (FILE *ferr); -void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, +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_memsetup(void); void qh_memsize(int size); -void qh_memstatistics (FILE *fp); +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/merge.c b/src/merge.c index cb683de..660358c 100644 --- a/src/merge.c +++ b/src/merge.c @@ -10,24 +10,26 @@ the user may call qh_postmerge() to perform additional merges. - To remove deleted facets and vertices (qhull() in qhull.c): - qh_partitionvisible (!qh_ALL, &numoutside); // visible_list, newfacet_list - qh_deletevisible (); // qh.visible_list - qh_resetlists (False, qh_RESETvisible); // qh.visible_list newvertex_list newfacet_list + To remove deleted facets and vertices (qhull() in qhulllib.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-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/merge.c#21 $$Change: 1095 $ + $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ */ #include "qhull_a.h" #ifndef qh_NOmerge -/*===== functions (alphabetical after premerge and postmerge) ======*/ +/*===== functions(alphabetical after premerge and postmerge) ======*/ /*-<a href="qh-merge.htm#TOC" >-------------------------------</a><a name="premerge">-</a> @@ -51,38 +53,38 @@ collect coplanar and concave facets merge concave, coplanar, degenerate, and redundant facets */ -void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle) { +void qh_premerge(vertexT *apex, realT maxcentrum, realT maxangle) { boolT othermerge= False; facetT *newfacet; if (qh ZEROcentrum && qh_checkzero(!qh_ALL)) return; - trace2((qh ferr, "qh_premerge: premerge centrum %2.2g angle %2.2g for apex v%d facetlist f%d\n", + 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); + 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 */); + 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); + 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); + 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_getmergeset_initial(qh newfacet_list); + qh_all_merges(othermerge, False); } qh_settempfree(&qh facet_mergeset); qh_settempfree(&qh degen_mergeset); @@ -124,27 +126,27 @@ void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle) { determine non-convex facets merge all non-convex facets */ -void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, +void qh_postmerge(char *reason, realT maxcentrum, realT maxangle, boolT vneighbors) { facetT *newfacet; boolT othermerges= False; vertexT *vertex; if (qh REPORTfreq || qh IStracing) { - qh_buildtracing (NULL, NULL); - qh_printsummary (qh ferr); + qh_buildtracing(NULL, NULL); + qh_printsummary(qh ferr); if (qh PRINTstatistics) - qh_printallstatistics (qh ferr, "reason"); - fprintf (qh ferr, "\n%s with 'C%.2g' and 'A%.2g'\n", + 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, "qh_postmerge: postmerge. test vneighbors? %d\n", + 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); + 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; @@ -166,10 +168,10 @@ void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, } } if (!qh PREmerge && !qh MERGEexact) - qh_flippedmerges (qh newfacet_list, &othermerges); + qh_flippedmerges(qh newfacet_list, &othermerges); } - qh_getmergeset_initial (qh newfacet_list); - qh_all_merges (False, vneighbors); + qh_getmergeset_initial(qh newfacet_list); + qh_all_merges(False, vneighbors); qh_settempfree(&qh facet_mergeset); qh_settempfree(&qh degen_mergeset); } /* post_merge */ @@ -210,7 +212,7 @@ void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, if vneighbors ?? tests vertex neighbors for convexity at end */ -void qh_all_merges (boolT othermerge, boolT vneighbors) { +void qh_all_merges(boolT othermerge, boolT vneighbors) { facetT *facet1, *facet2; mergeT *merge; boolT wasmerge= True, isreduce; @@ -219,11 +221,11 @@ void qh_all_merges (boolT othermerge, boolT vneighbors) { mergeType mergetype; int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0; - trace2((qh ferr, "qh_all_merges: starting to merge facets beginning from f%d\n", + 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 (qh_setsize(qh facet_mergeset)) { while ((merge= (mergeT*)qh_setdellast(qh facet_mergeset))) { facet1= merge->facet1; facet2= merge->facet2; @@ -236,7 +238,7 @@ void qh_all_merges (boolT othermerge, boolT vneighbors) { if (qh MERGEindependent && mergetype <= MRGanglecoplanar) continue; /* perform independent sets of merges */ } - qh_merge_nonconvex (facet1, facet2, mergetype); + qh_merge_nonconvex(facet1, facet2, mergetype); numdegenredun += qh_merge_degenredundant(); numnewmerges++; wasmerge= True; @@ -250,7 +252,7 @@ void qh_all_merges (boolT othermerge, boolT vneighbors) { numnewmerges= 0; qh_reducevertices(); /* otherwise large post merges too slow */ } - qh_getmergeset (qh newfacet_list); /* facet_mergeset */ + qh_getmergeset(qh newfacet_list); /* facet_mergeset */ } /* while mergeset */ if (qh VERTEXneighbors) { isreduce= False; @@ -266,7 +268,7 @@ void qh_all_merges (boolT othermerge, boolT vneighbors) { } if (isreduce) { if (qh_reducevertices()) { - qh_getmergeset (qh newfacet_list); /* facet_mergeset */ + qh_getmergeset(qh newfacet_list); /* facet_mergeset */ continue; } } @@ -278,14 +280,14 @@ void qh_all_merges (boolT othermerge, boolT vneighbors) { 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_checkconvex(qh newfacet_list, qh_ALGORITHMfault); + /* qh_checkconnect(); [this is slow and it changes the facet order] */ qh RANDOMdist= qh old_randomdist; } - trace1((qh ferr, "qh_all_merges: merged %d coplanar facets %d concave facets and %d degen or redundant facets.\n", + 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 (); + qh_printlists(); } /* all_merges */ @@ -330,31 +332,31 @@ void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, rea if (angle && qh ANGLEmerge) merge->angle= *angle; if (mergetype < MRGdegen) - qh_setappend (&(qh facet_mergeset), merge); + qh_setappend(&(qh facet_mergeset), merge); else if (mergetype == MRGdegen) { facet->degenerate= True; - if (!(lastmerge= (mergeT*)qh_setlast (qh degen_mergeset)) + if (!(lastmerge= (mergeT*)qh_setlast(qh degen_mergeset)) || lastmerge->type == MRGdegen) - qh_setappend (&(qh degen_mergeset), merge); + qh_setappend(&(qh degen_mergeset), merge); else - qh_setaddnth (&(qh degen_mergeset), 0, merge); + qh_setaddnth(&(qh degen_mergeset), 0, merge); }else if (mergetype == MRGredundant) { facet->redundant= True; - qh_setappend (&(qh degen_mergeset), merge); + qh_setappend(&(qh degen_mergeset), merge); }else /* mergetype == MRGmirror */ { if (facet->redundant || neighbor->redundant) { - fprintf(qh ferr, "qhull error (qh_appendmergeset): facet f%d or f%d is already a mirrored facet\n", + 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)) { - fprintf(qh ferr, "qhull error (qh_appendmergeset): mirrored facets f%d and f%d do not have the same vertices\n", + 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); + qh_setappend(&(qh degen_mergeset), merge); } } /* appendmergeset */ @@ -368,7 +370,7 @@ void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, rea assumes apex is SETfirst_( samecycle->vertices ) returns: - vertices (settemp) + vertices(settemp) all ->seen are cleared notes: @@ -379,10 +381,10 @@ void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, rea for each unseen vertex in facet->vertices append to result */ -setT *qh_basevertices (facetT *samecycle) { +setT *qh_basevertices(facetT *samecycle) { facetT *same; vertexT *apex, *vertex, **vertexp; - setT *vertices= qh_settemp (qh TEMPsize); + setT *vertices= qh_settemp(qh TEMPsize); apex= SETfirstt_(samecycle->vertices, vertexT); apex->visitid= ++qh vertex_visit; @@ -391,14 +393,14 @@ setT *qh_basevertices (facetT *samecycle) { continue; FOREACHvertex_(same->vertices) { if (vertex->visitid != qh vertex_visit) { - qh_setappend (&vertices, vertex); + qh_setappend(&vertices, vertex); vertex->visitid= qh vertex_visit; vertex->seen= False; } } } - trace4((qh ferr, "qh_basevertices: found %d vertices\n", - qh_setsize (vertices))); + trace4((qh ferr, 4019, "qh_basevertices: found %d vertices\n", + qh_setsize(vertices))); return vertices; } /* basevertices */ @@ -420,18 +422,18 @@ setT *qh_basevertices (facetT *samecycle) { for all new facets report error if unvisited */ -void qh_checkconnect (void /* qh newfacet_list */) { +void qh_checkconnect(void /* qh newfacet_list */) { facetT *facet, *newfacet, *errfacet= NULL, *neighbor, **neighborp; facet= qh newfacet_list; - qh_removefacet (facet); - qh_appendfacet (facet); + 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); + qh_removefacet(neighbor); + qh_appendfacet(neighbor); neighbor->visitid= qh visit_id; } } @@ -439,12 +441,12 @@ void qh_checkconnect (void /* qh newfacet_list */) { FORALLnew_facets { if (newfacet->visitid == qh visit_id) break; - fprintf(qh ferr, "qhull error: f%d is not attached to the new facets\n", + 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); + qh_errexit(qh_ERRqhull, errfacet, NULL); } /* checkconnect */ /*-<a href="qh-merge.htm#TOC" @@ -483,7 +485,7 @@ void qh_checkconnect (void /* qh newfacet_list */) { if qh.newfacet_list test the other vertices in the facet's horizon facet */ -boolT qh_checkzero (boolT testall) { +boolT qh_checkzero(boolT testall) { facetT *facet, *neighbor, **neighborp; facetT *horizon, *facetlist; int neighbor_i; @@ -502,7 +504,7 @@ boolT qh_checkzero (boolT testall) { goto LABELproblem; } if (qh MERGEexact && qh ZEROall_ok) { - trace2((qh ferr, "qh_checkzero: skip convexity check until first pre-merge\n")); + trace2((qh ferr, 2011, "qh_checkzero: skip convexity check until first pre-merge\n")); return True; } } @@ -519,7 +521,7 @@ boolT qh_checkzero (boolT testall) { vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT); vertex->visitid= qh vertex_visit; zzinc_(Zdistzero); - qh_distplane (vertex->point, neighbor, &dist); + qh_distplane(vertex->point, neighbor, &dist); if (dist >= -qh DISTround) { qh ZEROall_ok= False; if (!qh MERGEexact || testall || dist > qh DISTround) @@ -530,7 +532,7 @@ boolT qh_checkzero (boolT testall) { FOREACHvertex_(horizon->vertices) { if (vertex->visitid != qh vertex_visit) { zzinc_(Zdistzero); - qh_distplane (vertex->point, facet, &dist); + qh_distplane(vertex->point, facet, &dist); if (dist >= -qh DISTround) { qh ZEROall_ok= False; if (!qh MERGEexact || dist > qh DISTround) @@ -541,19 +543,19 @@ boolT qh_checkzero (boolT testall) { } } } - trace2((qh ferr, "qh_checkzero: testall %d, facets are %s\n", testall, + 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, "qh_checkzero: facet f%d needs pre-merging\n", + trace2((qh ferr, 2013, "qh_checkzero: facet f%d needs pre-merging\n", facet->id)); return False; LABELnonconvex: - trace2((qh ferr, "qh_checkzero: facet f%d and f%d are not clearly convex. v%d dist %.2g\n", + 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 */ @@ -567,7 +569,7 @@ boolT qh_checkzero (boolT testall) { int qh_compareangle(const void *p1, const void *p2) { mergeT *a= *((mergeT **)p1), *b= *((mergeT **)p2); - return ((a->angle > b->angle) ? 1 : -1); + return((a->angle > b->angle) ? 1 : -1); } /* compareangle */ /*-<a href="qh-merge.htm#TOC" @@ -579,7 +581,7 @@ int qh_compareangle(const void *p1, const void *p2) { int qh_comparemerge(const void *p1, const void *p2) { mergeT *a= *((mergeT **)p1), *b= *((mergeT **)p2); - return (a->type - b->type); + return(a->type - b->type); } /* comparemerge */ /*-<a href="qh-merge.htm#TOC" @@ -588,10 +590,10 @@ int qh_comparemerge(const void *p1, const void *p2) { qh_comparevisit( vertex1, vertex2 ) used by qsort() to order vertices by their visitid */ -int qh_comparevisit (const void *p1, const void *p2) { +int qh_comparevisit(const void *p1, const void *p2) { vertexT *a= *((vertexT **)p1), *b= *((vertexT **)p2); - return (a->visitid - b->visitid); + return(a->visitid - b->visitid); } /* comparevisit */ /*-<a href="qh-merge.htm#TOC" @@ -608,7 +610,7 @@ int qh_comparevisit (const void *p1, const void *p2) { if ridge shares the same neighbor set nonconvex flag */ -void qh_copynonconvex (ridgeT *atridge) { +void qh_copynonconvex(ridgeT *atridge) { facetT *facet, *otherfacet; ridgeT *ridge, **ridgep; @@ -617,7 +619,7 @@ void qh_copynonconvex (ridgeT *atridge) { FOREACHridge_(facet->ridges) { if (otherfacet == otherfacet_(ridge, facet) && ridge != atridge) { ridge->nonconvex= True; - trace4((qh ferr, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n", + trace4((qh ferr, 4020, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n", atridge->id, ridge->id)); break; } @@ -642,11 +644,11 @@ void qh_copynonconvex (ridgeT *atridge) { test for redundant neighbor test for degenerate facet */ -void qh_degen_redundant_facet (facetT *facet) { +void qh_degen_redundant_facet(facetT *facet) { vertexT *vertex, **vertexp; facetT *neighbor, **neighborp; - trace4((qh ferr, "qh_degen_redundant_facet: test facet f%d for degen/redundant\n", + trace4((qh ferr, 4021, "qh_degen_redundant_facet: test facet f%d for degen/redundant\n", facet->id)); FOREACHneighbor_(facet) { qh vertex_visit++; @@ -657,14 +659,14 @@ void qh_degen_redundant_facet (facetT *facet) { break; } if (!vertex) { - qh_appendmergeset (facet, neighbor, MRGredundant, NULL); - trace2((qh ferr, "qh_degen_redundant_facet: f%d is contained in f%d. merge\n", facet->id, neighbor->id)); + 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, "qh_degen_redundant_neighbors: f%d is degenerate.\n", facet->id)); + 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 */ @@ -698,16 +700,16 @@ void qh_degen_redundant_facet (facetT *facet) { test for redundant neighbor test for degenerate neighbor */ -void qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet) { +void qh_degen_redundant_neighbors(facetT *facet, facetT *delfacet) { vertexT *vertex, **vertexp; facetT *neighbor, **neighborp; int size; - trace4((qh ferr, "qh_degen_redundant_neighbors: test neighbors of f%d with delfacet f%d\n", + 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, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.\n", facet->id, size)); + 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; @@ -723,16 +725,16 @@ void qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet) { break; } if (!vertex) { - qh_appendmergeset (neighbor, facet, MRGredundant, NULL); - trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is contained in f%d. merge\n", neighbor->id, facet->id)); + 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, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors. Neighbor of f%d.\n", neighbor->id, size, facet->id)); + 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 */ @@ -768,7 +770,7 @@ void qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet) { 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 *qh_find_newvertex(vertexT *oldvertex, setT *vertices, setT *ridges) { vertexT *vertex, **vertexp; setT *newridges; ridgeT *ridge, **ridgep; @@ -777,13 +779,13 @@ vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges) { #ifndef qh_NOtrace if (qh IStracing >= 4) { - fprintf (qh ferr, "qh_find_newvertex: find new vertex for v%d from ", + qh_fprintf(qh ferr, 8063, "qh_find_newvertex: find new vertex for v%d from ", oldvertex->id); FOREACHvertex_(vertices) - fprintf (qh ferr, "v%d ", vertex->id); + qh_fprintf(qh ferr, 8064, "v%d ", vertex->id); FOREACHridge_(ridges) - fprintf (qh ferr, "r%d ", ridge->id); - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 8065, "r%d ", ridge->id); + qh_fprintf(qh ferr, 8066, "\n"); } #endif FOREACHvertex_(vertices) @@ -794,50 +796,50 @@ vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges) { } FOREACHvertex_(vertices) { if (!vertex->visitid) { - qh_setdelnth (vertices, SETindex_(vertices,vertex)); + qh_setdelnth(vertices, SETindex_(vertices,vertex)); vertexp--; /* repeat since deleted this vertex */ } } - qh vertex_visit += qh_setsize (ridges); - if (!qh_setsize (vertices)) { - trace4((qh ferr, "qh_find_newvertex: vertices not in ridges for v%d\n", + qh vertex_visit += 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), qh_setsize (vertices), - sizeof (vertexT *), qh_comparevisit); + qsort(SETaddr_(vertices, vertexT), qh_setsize(vertices), + sizeof(vertexT *), qh_comparevisit); /* can now use qh vertex_visit */ if (qh PRINTstatistics) { - size= qh_setsize (vertices); + size= qh_setsize(vertices); zinc_(Zintersect); zadd_(Zintersecttot, size); zmax_(Zintersectmax, size); } - hashsize= qh_newhashtable (qh_setsize (ridges)); + hashsize= qh_newhashtable(qh_setsize(ridges)); FOREACHridge_(ridges) - qh_hashridge (qh hash_table, hashsize, ridge, oldvertex); + qh_hashridge(qh hash_table, hashsize, ridge, oldvertex); FOREACHvertex_(vertices) { - newridges= qh_vertexridges (vertex); + newridges= qh_vertexridges(vertex); FOREACHridge_(newridges) { - if (qh_hashridge_find (qh hash_table, hashsize, ridge, vertex, oldvertex, &hash)) { + if (qh_hashridge_find(qh hash_table, hashsize, ridge, vertex, oldvertex, &hash)) { zinc_(Zdupridge); break; } } - qh_settempfree (&newridges); + qh_settempfree(&newridges); if (!ridge) break; /* found a rename */ } if (vertex) { /* counted in qh_renamevertex */ - trace2((qh ferr, "qh_find_newvertex: found v%d for old v%d from %d vertices and %d ridges.\n", - vertex->id, oldvertex->id, qh_setsize (vertices), qh_setsize (ridges))); + 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, "qh_find_newvertex: no vertex for renaming v%d (all duplicated ridges) during p%d\n", + 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); + qh_setfree(&qh hash_table); return vertex; } /* find_newvertex */ @@ -855,7 +857,7 @@ vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges) { 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, +void qh_findbest_test(boolT testcentrum, facetT *facet, facetT *neighbor, facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp) { realT dist, mindist, maxdist; @@ -867,10 +869,12 @@ void qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor, maxdist= 0; mindist= dist; dist= -dist; - }else + }else { + mindist= 0; maxdist= dist; + } }else - dist= qh_getdistance (facet, neighbor, &mindist, &maxdist); + dist= qh_getdistance(facet, neighbor, &mindist, &maxdist); if (dist < *distp) { *bestfacet= neighbor; *mindistp= mindist; @@ -909,20 +913,20 @@ facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT facetT *neighbor, **neighborp, *bestfacet= NULL; ridgeT *ridge, **ridgep; boolT nonconvex= True, testcentrum= False; - int size= qh_setsize (facet->vertices); + 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); + 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, + qh_findbest_test(testcentrum, facet, neighbor, &bestfacet, distp, mindistp, maxdistp); } } @@ -930,17 +934,17 @@ facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT if (!bestfacet) { nonconvex= False; FOREACHneighbor_(facet) - qh_findbest_test (testcentrum, facet, neighbor, + qh_findbest_test(testcentrum, facet, neighbor, &bestfacet, distp, mindistp, maxdistp); } if (!bestfacet) { - fprintf (qh ferr, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id); + qh_fprintf(qh ferr, 6095, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id); - qh_errexit (qh_ERRqhull, facet, NULL); + qh_errexit(qh_ERRqhull, facet, NULL); } if (testcentrum) - qh_getdistance (facet, bestfacet, mindistp, maxdistp); - trace3((qh ferr, "qh_findbestneighbor: f%d is best neighbor for f%d testcentrum? %d nonconvex? %d dist %2.2g min %2.2g max %2.2g\n", + 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 */ @@ -977,24 +981,24 @@ void qh_flippedmerges(facetT *facetlist, boolT *wasmerge) { setT *othermerges; int nummerge=0; - trace4((qh ferr, "qh_flippedmerges: begin\n")); + trace4((qh ferr, 4024, "qh_flippedmerges: begin\n")); FORALLfacet_(facetlist) { if (facet->flipped && !facet->visible) - qh_appendmergeset (facet, facet, MRGflip, NULL); + qh_appendmergeset(facet, facet, MRGflip, NULL); } othermerges= qh_settemppop(); /* was facet_mergeset */ - qh facet_mergeset= qh_settemp (qh TEMPsize); - qh_settemppush (othermerges); + qh facet_mergeset= qh_settemp(qh TEMPsize); + qh_settemppush(othermerges); FOREACHmerge_(othermerges) { facet1= merge->facet1; if (merge->type != MRGflip || facet1->visible) continue; if (qh TRACEmerge-1 == zzval_(Ztotmerge)) qhmem.IStracing= qh IStracing= qh TRACElevel; - neighbor= qh_findbestneighbor (facet1, &dist, &mindist, &maxdist); - trace0((qh ferr, "qh_flippedmerges: merge flipped f%d into f%d dist %2.2g during p%d\n", + 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); + qh_mergefacet(facet1, neighbor, &mindist, &maxdist, !qh_MERGEapex); nummerge++; if (qh PRINTstatistics) { zinc_(Zflipped); @@ -1005,14 +1009,14 @@ void qh_flippedmerges(facetT *facetlist, boolT *wasmerge) { } FOREACHmerge_(othermerges) { if (merge->facet1->visible || merge->facet2->visible) - qh_memfree (merge, sizeof(mergeT)); + qh_memfree(merge, sizeof(mergeT)); else - qh_setappend (&qh facet_mergeset, merge); + qh_setappend(&qh facet_mergeset, merge); } - qh_settempfree (&othermerges); + qh_settempfree(&othermerges); if (nummerge) *wasmerge= True; - trace1((qh ferr, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge)); + trace1((qh ferr, 1010, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge)); } /* flippedmerges */ @@ -1025,7 +1029,7 @@ void qh_flippedmerges(facetT *facetlist, boolT *wasmerge) { returns: removes all duplicate ridges on facet_mergeset wasmerge set if merge - qh.facet_mergeset may include non-forced merges (none for now) + qh.facet_mergeset may include non-forced merges(none for now) qh.degen_mergeset includes degen/redun merges notes: @@ -1052,10 +1056,10 @@ void qh_forcedmerges(boolT *wasmerge) { if (qh TRACEmerge-1 == zzval_(Ztotmerge)) qhmem.IStracing= qh IStracing= qh TRACElevel; - trace4((qh ferr, "qh_forcedmerges: begin\n")); + trace4((qh ferr, 4025, "qh_forcedmerges: begin\n")); othermerges= qh_settemppop(); /* was facet_mergeset */ - qh facet_mergeset= qh_settemp (qh TEMPsize); - qh_settemppush (othermerges); + qh facet_mergeset= qh_settemp(qh TEMPsize); + qh_settemppush(othermerges); FOREACHmerge_(othermerges) { if (merge->type != MRGridge) continue; @@ -1067,21 +1071,21 @@ void qh_forcedmerges(boolT *wasmerge) { facet2= facet2->f.replace; /* previously merged facet */ if (facet1 == facet2) continue; - if (!qh_setin (facet2->neighbors, facet1)) { - fprintf (qh ferr, "qhull internal error (qh_forcedmerges): f%d and f%d had a duplicate ridge but as f%d and f%d they are no longer neighbors\n", + 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, "qh_forcedmerges: duplicate ridge between f%d and f%d, dist %2.2g and reverse dist %2.2g during p%d\n", + 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); + qh_mergefacet(facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex); else { - qh_mergefacet (facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex); + qh_mergefacet(facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex); dist1= dist2; facet1= facet2; } @@ -1098,14 +1102,14 @@ void qh_forcedmerges(boolT *wasmerge) { } FOREACHmerge_(othermerges) { if (merge->type == MRGridge) - qh_memfree (merge, sizeof(mergeT)); + qh_memfree(merge, sizeof(mergeT)); else - qh_setappend (&qh facet_mergeset, merge); + qh_setappend(&qh facet_mergeset, merge); } - qh_settempfree (&othermerges); + qh_settempfree(&othermerges); if (nummerge) *wasmerge= True; - trace1((qh ferr, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n", + trace1((qh ferr, 1011, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n", nummerge, numflip)); } /* forcedmerges */ @@ -1144,8 +1148,8 @@ void qh_getmergeset(facetT *facetlist) { ridgeT *ridge, **ridgep; int nummerges; - nummerges= qh_setsize (qh facet_mergeset); - trace4((qh ferr, "qh_getmergeset: started.\n")); + nummerges= qh_setsize(qh facet_mergeset); + trace4((qh ferr, 4026, "qh_getmergeset: started.\n")); qh visit_id++; FORALLfacet_(facetlist) { if (facet->tested) @@ -1166,12 +1170,12 @@ void qh_getmergeset(facetT *facetlist) { ridge->tested= True; ridge->nonconvex= False; neighbor->seen= True; /* only one ridge is marked nonconvex */ - if (qh_test_appendmerge (facet, neighbor)) + if (qh_test_appendmerge(facet, neighbor)) ridge->nonconvex= True; } } } - nummerges= qh_setsize (qh facet_mergeset); + nummerges= qh_setsize(qh facet_mergeset); if (qh ANGLEmerge) qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_compareangle); else @@ -1182,7 +1186,7 @@ void qh_getmergeset(facetT *facetlist) { zadd_(Zmergesettot, nummerges); zmax_(Zmergesetmax, nummerges); } - trace2((qh ferr, "qh_getmergeset: %d merges found\n", nummerges)); + trace2((qh ferr, 2021, "qh_getmergeset: %d merges found\n", nummerges)); } /* getmergeset */ @@ -1212,7 +1216,7 @@ void qh_getmergeset(facetT *facetlist) { mark one of the ridges as nonconvex sort qh.facet_mergeset by angle */ -void qh_getmergeset_initial (facetT *facetlist) { +void qh_getmergeset_initial(facetT *facetlist) { facetT *facet, *neighbor, **neighborp; ridgeT *ridge, **ridgep; int nummerges; @@ -1223,7 +1227,7 @@ void qh_getmergeset_initial (facetT *facetlist) { facet->tested= True; FOREACHneighbor_(facet) { if (neighbor->visitid != qh visit_id) { - if (qh_test_appendmerge (facet, neighbor)) { + if (qh_test_appendmerge(facet, neighbor)) { FOREACHridge_(neighbor->ridges) { if (facet == otherfacet_(ridge, neighbor)) { ridge->nonconvex= True; @@ -1236,7 +1240,7 @@ void qh_getmergeset_initial (facetT *facetlist) { FOREACHridge_(facet->ridges) ridge->tested= True; } - nummerges= qh_setsize (qh facet_mergeset); + nummerges= qh_setsize(qh facet_mergeset); if (qh ANGLEmerge) qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_compareangle); else @@ -1247,7 +1251,7 @@ void qh_getmergeset_initial (facetT *facetlist) { zadd_(Zmergeinittot, nummerges); zmax_(Zmergeinitmax, nummerges); } - trace2((qh ferr, "qh_getmergeset_initial: %d merges found\n", nummerges)); + trace2((qh ferr, 2022, "qh_getmergeset_initial: %d merges found\n", nummerges)); } /* getmergeset_initial */ @@ -1264,11 +1268,11 @@ void qh_getmergeset_initial (facetT *facetlist) { determine hash value for ridge without oldvertex find next empty slot for ridge */ -void qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) { +void qh_hashridge(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) { int hash; ridgeT *ridgeA; - hash= (int)qh_gethash (hashsize, ridge->vertices, qh hull_dim-1, 0, oldvertex); + hash= (int)qh_gethash(hashsize, ridge->vertices, qh hull_dim-1, 0, oldvertex); while (True) { if (!(ridgeA= SETelemt_(hashtable, hash, ridgeT))) { SETelem_(hashtable, hash)= ridge; @@ -1307,20 +1311,20 @@ void qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldver for each hashslot return match if ridge matches ridgeA without oldvertex */ -ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, +ridgeT *qh_hashridge_find(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *vertex, vertexT *oldvertex, int *hashslot) { int hash; ridgeT *ridgeA; *hashslot= 0; zinc_(Zhashridge); - hash= (int)qh_gethash (hashsize, ridge->vertices, qh hull_dim-1, 0, vertex); + hash= (int)qh_gethash(hashsize, ridge->vertices, qh hull_dim-1, 0, vertex); while ((ridgeA= SETelemt_(hashtable, hash, ridgeT))) { if (ridgeA == ridge) *hashslot= -1; else { zinc_(Zhashridgetest); - if (qh_setequal_except (ridge->vertices, vertex, ridgeA->vertices, oldvertex)) + if (qh_setequal_except(ridge->vertices, vertex, ridgeA->vertices, oldvertex)) return ridgeA; } if (++hash == hashsize) @@ -1366,7 +1370,7 @@ void qh_makeridges(facetT *facet) { if (!facet->simplicial) return; - trace4((qh ferr, "qh_makeridges: make ridges for f%d\n", facet->id)); + trace4((qh ferr, 4027, "qh_makeridges: make ridges for f%d\n", facet->id)); facet->simplicial= False; FOREACHneighbor_(facet) { if (neighbor == qh_MERGEridge) @@ -1381,7 +1385,7 @@ void qh_makeridges(facetT *facet) { 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, + ridge->vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim, neighbor_i, 0); toporient= facet->toporient ^ (neighbor_i & 0x1); if (toporient) { @@ -1406,7 +1410,7 @@ void qh_makeridges(facetT *facet) { } } if (mergeridge) { - while (qh_setdel (facet->neighbors, qh_MERGEridge)) + while (qh_setdel(facet->neighbors, qh_MERGEridge)) ; /* delete each one */ } } /* makeridges */ @@ -1454,7 +1458,7 @@ void qh_mark_dupridges(facetT *facetlist) { mergeT *merge, **mergep; - trace4((qh ferr, "qh_mark_dupridges: identify duplicate ridges\n")); + trace4((qh ferr, 4028, "qh_mark_dupridges: identify duplicate ridges\n")); FORALLfacet_(facetlist) { if (facet->dupridge) { FOREACHneighbor_(facet) { @@ -1463,8 +1467,8 @@ void qh_mark_dupridges(facetT *facetlist) { continue; } if (neighbor->dupridge - && !qh_setin (neighbor->neighbors, facet)) { /* qh_MERGEridge */ - qh_appendmergeset (facet, neighbor, MRGridge, NULL); + && !qh_setin(neighbor->neighbors, facet)) { /* qh_MERGEridge */ + qh_appendmergeset(facet, neighbor, MRGridge, NULL); facet->mergeridge2= True; facet->mergeridge= True; nummerge++; @@ -1476,15 +1480,15 @@ void qh_mark_dupridges(facetT *facetlist) { return; FORALLfacet_(facetlist) { /* gets rid of qh_MERGEridge */ if (facet->mergeridge && !facet->mergeridge2) - qh_makeridges (facet); + 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 */ + qh_setappend(&merge->facet2->neighbors, merge->facet1); + qh_makeridges(merge->facet1); /* and the missing ridges */ } } - trace1((qh ferr, "qh_mark_dupridges: found %d duplicated ridges\n", + trace1((qh ferr, 1012, "qh_mark_dupridges: found %d duplicated ridges\n", nummerge)); } /* mark_dupridges */ @@ -1512,13 +1516,13 @@ void qh_mark_dupridges(facetT *facetlist) { if facet is degenerate append facet to qh.degen_mergeset */ -void qh_maydropneighbor (facetT *facet) { +void qh_maydropneighbor(facetT *facet) { ridgeT *ridge, **ridgep; realT angledegen= qh_ANGLEdegen; facetT *neighbor, **neighborp; qh visit_id++; - trace4((qh ferr, "qh_maydropneighbor: test f%d for no ridges to a neighbor\n", + 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; @@ -1526,23 +1530,23 @@ void qh_maydropneighbor (facetT *facet) { } FOREACHneighbor_(facet) { if (neighbor->visitid != qh visit_id) { - trace0((qh ferr, "qh_maydropneighbor: facets f%d and f%d are no longer neighbors during p%d\n", + 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); + qh_setdel(facet->neighbors, neighbor); neighborp--; /* repeat, deleted a neighbor */ - qh_setdel (neighbor->neighbors, facet); - if (qh_setsize (neighbor->neighbors) < qh hull_dim) { + qh_setdel(neighbor->neighbors, facet); + if (qh_setsize(neighbor->neighbors) < qh hull_dim) { zinc_(Zdropdegen); - qh_appendmergeset (neighbor, neighbor, MRGdegen, &angledegen); - trace2((qh ferr, "qh_maydropneighbors: f%d is degenerate.\n", neighbor->id)); + 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) { + if (qh_setsize(facet->neighbors) < qh hull_dim) { zinc_(Zdropdegen); - qh_appendmergeset (facet, facet, MRGdegen, &angledegen); - trace2((qh ferr, "qh_maydropneighbors: f%d is degenerate.\n", facet->id)); + qh_appendmergeset(facet, facet, MRGdegen, &angledegen); + trace2((qh ferr, 2024, "qh_maydropneighbors: f%d is degenerate.\n", facet->id)); } } /* maydropneighbor */ @@ -1572,7 +1576,7 @@ void qh_maydropneighbor (facetT *facet) { else merge redundant facet into other facet */ -int qh_merge_degenredundant (void) { +int qh_merge_degenredundant(void) { int size; mergeT *merge; facetT *bestneighbor, *facet1, *facet2; @@ -1581,11 +1585,11 @@ int qh_merge_degenredundant (void) { int nummerges= 0; mergeType mergetype; - while ((merge= (mergeT*)qh_setdellast (qh degen_mergeset))) { + while ((merge= (mergeT*)qh_setdellast(qh degen_mergeset))) { facet1= merge->facet1; facet2= merge->facet2; mergetype= merge->type; - qh_memfree (merge, sizeof(mergeT)); + qh_memfree(merge, sizeof(mergeT)); if (facet1->visible) continue; facet1->degenerate= False; @@ -1596,40 +1600,40 @@ int qh_merge_degenredundant (void) { zinc_(Zneighbor); while (facet2->visible) { if (!facet2->f.replace) { - fprintf (qh ferr, "qhull internal error (qh_merge_degenredunant): f%d redundant but f%d has no replacement\n", + 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 */ + qh_degen_redundant_facet(facet1); /* in case of others */ continue; } - trace2((qh ferr, "qh_merge_degenredundant: facet f%d is contained in f%d, will merge\n", + 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))) { + if (!(size= qh_setsize(facet1->neighbors))) { zinc_(Zdelfacetdup); - trace2((qh ferr, "qh_merge_degenredundant: facet f%d has no neighbors. Deleted\n", facet1->id)); - qh_willdelete (facet1, NULL); + 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); + qh_setdel(vertex->neighbors, facet1); if (!SETfirst_(vertex->neighbors)) { zinc_(Zdegenvertex); - trace2((qh ferr, "qh_merge_degenredundant: deleted v%d because f%d has no neighbors\n", + 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); + qh_setappend(&qh del_vertices, vertex); } } nummerges++; }else if (size < qh hull_dim) { bestneighbor= qh_findbestneighbor(facet1, &dist, &mindist, &maxdist); - trace2((qh ferr, "qh_merge_degenredundant: facet f%d has %d neighbors, merge into f%d dist %2.2g\n", + 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++; @@ -1661,13 +1665,13 @@ int qh_merge_degenredundant (void) { merge the nearest facet into its best neighbor update the statistics */ -void qh_merge_nonconvex (facetT *facet1, facetT *facet2, mergeType mergetype) { +void qh_merge_nonconvex(facetT *facet1, facetT *facet2, mergeType mergetype) { facetT *bestfacet, *bestneighbor, *neighbor; realT dist, dist2, mindist, mindist2, maxdist, maxdist2; if (qh TRACEmerge-1 == zzval_(Ztotmerge)) qhmem.IStracing= qh IStracing= qh TRACElevel; - trace3((qh ferr, "qh_merge_nonconvex: merge #%d for f%d and f%d type %d\n", + 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) { @@ -1686,7 +1690,7 @@ void qh_merge_nonconvex (facetT *facet1, facetT *facet2, mergeType mergetype) { zinc_(Zavoidold); wadd_(Wavoidoldtot, dist); wmax_(Wavoidoldmax, dist); - trace2((qh ferr, "qh_merge_nonconvex: avoid merging old facet f%d dist %2.2g. Use f%d dist %2.2g instead\n", + 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 { @@ -1739,7 +1743,7 @@ void qh_merge_nonconvex (facetT *facet1, facetT *facet2, mergeType mergetype) { add its vertices to qh.newvertex_list delete samecycle facets a make newfacet a newfacet */ -void qh_mergecycle (facetT *samecycle, facetT *newfacet) { +void qh_mergecycle(facetT *samecycle, facetT *newfacet) { int traceonce= False, tracerestore= 0; vertexT *apex; #ifndef qh_NOtrace @@ -1748,8 +1752,8 @@ void qh_mergecycle (facetT *samecycle, facetT *newfacet) { if (newfacet->tricoplanar) { if (!qh TRInormals) { - fprintf (qh ferr, "qh_mergecycle: does not work for tricoplanar facets. Use option 'Q11'\n"); - qh_errexit (qh_ERRqhull, newfacet, NULL); + 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; @@ -1764,38 +1768,38 @@ void qh_mergecycle (facetT *samecycle, facetT *newfacet) { #ifndef qh_NOtrace if (qh TRACEmerge == zzval_(Ztotmerge)) qhmem.IStracing= qh IStracing= qh TRACElevel; - trace2((qh ferr, "qh_mergecycle: merge #%d for facets from cycle f%d into coplanar horizon f%d\n", + 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; - fprintf (qh ferr, "qh_mergecycle: ========= trace merge %d of samecycle %d into trace f%d, furthest is p%d\n", + 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) { - fprintf (qh ferr, " same cycle:"); + qh_fprintf(qh ferr, 8069, " same cycle:"); FORALLsame_cycle_(samecycle) - fprintf(qh ferr, " f%d", same->id); - fprintf (qh ferr, "\n"); + 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); + 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); + 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 */ + 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); + qh_newvertices(newfacet->vertices); + qh_mergecycle_facets(samecycle, newfacet); + qh_tracemerge(samecycle, newfacet); /* check for degen_redundant_neighbors after qh_forcedmerges() */ if (traceonce) { - fprintf (qh ferr, "qh_mergecycle: end of trace facet\n"); + qh_fprintf(qh ferr, 8072, "qh_mergecycle: end of trace facet\n"); qh IStracing= tracerestore; } } /* mergecycle */ @@ -1829,19 +1833,19 @@ void qh_mergecycle (facetT *samecycle, facetT *newfacet) { remove facets with duplicate ridges from samecycle merge samecycle into horizon (deletes facets from facetlist) */ -void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) { +void qh_mergecycle_all(facetT *facetlist, boolT *wasmerge) { facetT *facet, *same, *prev, *horizon; facetT *samecycle= NULL, *nextfacet, *nextsame; vertexT *apex, *vertex, **vertexp; int cycles=0, total=0, facets, nummerge; - trace2((qh ferr, "qh_mergecycle_all: begin\n")); + 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) { - fprintf (qh ferr, "qh_mergecycle_all: f%d without normal\n", facet->id); - qh_errexit (qh_ERRqhull, facet, NULL); + 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) { @@ -1853,7 +1857,7 @@ void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) { vertex->delridge= True; } horizon->f.newcycle= NULL; - qh_mergefacet (facet, horizon, NULL, NULL, qh_MERGEapex); + qh_mergefacet(facet, horizon, NULL, NULL, qh_MERGEapex); }else { samecycle= facet; facets= 0; @@ -1862,7 +1866,7 @@ void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) { same= (same == facet ? NULL :nextsame)) { /* ends at facet */ nextsame= same->f.samecycle; if (same->cycledone || same->visible) - qh_infiniteloop (same); + qh_infiniteloop(same); same->cycledone= True; if (same->normal) { prev->f.samecycle= same->f.samecycle; /* unlink ->mergeridge */ @@ -1875,7 +1879,7 @@ void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) { while (nextfacet && nextfacet->cycledone) /* will delete samecycle */ nextfacet= nextfacet->next; horizon->f.newcycle= NULL; - qh_mergecycle (samecycle, horizon); + qh_mergecycle(samecycle, horizon); nummerge= horizon->nummerge + facets; if (nummerge > qh_MAXnummerge) horizon->nummerge= qh_MAXnummerge; @@ -1890,7 +1894,7 @@ void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) { } if (cycles) *wasmerge= True; - trace1((qh ferr, "qh_mergecycle_all: merged %d same cycles or facets into coplanar horizons\n", cycles)); + 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" @@ -1917,10 +1921,10 @@ void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) { unless newfacet is large remove its centrum */ -void qh_mergecycle_facets (facetT *samecycle, facetT *newfacet) { +void qh_mergecycle_facets(facetT *samecycle, facetT *newfacet) { facetT *same, *next; - trace4((qh ferr, "qh_mergecycle_facets: make newfacet new and samecycle deleted\n")); + 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; @@ -1929,14 +1933,14 @@ void qh_mergecycle_facets (facetT *samecycle, facetT *newfacet) { for (same= samecycle->f.samecycle; same; same= (same == samecycle ? NULL : next)) { next= same->f.samecycle; /* reused by willdelete */ - qh_willdelete (same, newfacet); + qh_willdelete(same, newfacet); } if (newfacet->center - && qh_setsize (newfacet->vertices) <= qh hull_dim + qh_MAXnewcentrum) { - qh_memfree (newfacet->center, qh normal_size); + && qh_setsize(newfacet->vertices) <= qh hull_dim + qh_MAXnewcentrum) { + qh_memfree(newfacet->center, qh normal_size); newfacet->center= NULL; } - trace3((qh ferr, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n", + trace3((qh ferr, 3004, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n", samecycle->id, newfacet->id)); } /* mergecycle_facets */ @@ -1984,11 +1988,11 @@ void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet) { samevisitid= ++qh visit_id; FORALLsame_cycle_(samecycle) { if (same->visitid == samevisitid || same->visible) - qh_infiniteloop (samecycle); + qh_infiniteloop(samecycle); same->visitid= samevisitid; } newfacet->visitid= ++qh visit_id; - trace4((qh ferr, "qh_mergecycle_neighbors: delete shared neighbors from newfacet\n")); + 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 */ @@ -1996,17 +2000,17 @@ void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet) { }else neighbor->visitid= qh visit_id; } - qh_setcompact (newfacet->neighbors); + qh_setcompact(newfacet->neighbors); - trace4((qh ferr, "qh_mergecycle_neighbors: update neighbors\n")); + 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); + 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 */ @@ -2019,22 +2023,22 @@ void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet) { } } }else { - qh_makeridges (neighbor); - qh_setdel (neighbor->neighbors, same); + 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); + qh_setdel(neighbor->neighbors, same); if (neighbor->visitid != qh visit_id) { - qh_setappend (&neighbor->neighbors, newfacet); - qh_setappend (&newfacet->neighbors, neighbor); + qh_setappend(&neighbor->neighbors, newfacet); + qh_setappend(&newfacet->neighbors, neighbor); neighbor->visitid= qh visit_id; newneighbors++; } } } } - trace2((qh ferr, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n", + trace2((qh ferr, 2032, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n", delneighbors, newneighbors)); } /* mergecycle_neighbors */ @@ -2081,16 +2085,16 @@ void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) { boolT toporient; void **freelistp; /* used !qh_NOmem */ - trace4((qh ferr, "qh_mergecycle_ridges: delete shared ridges from newfacet\n")); + 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); + qh_setcompact(newfacet->ridges); - trace4((qh ferr, "qh_mergecycle_ridges: add ridges to newfacet\n")); + trace4((qh ferr, 4034, "qh_mergecycle_ridges: add ridges to newfacet\n")); FORALLsame_cycle_(samecycle) { FOREACHridge_(same->ridges) { if (ridge->top == same) { @@ -2100,35 +2104,35 @@ void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) { ridge->bottom= newfacet; neighbor= ridge->top; }else if (ridge->top == newfacet || ridge->bottom == newfacet) { - qh_setappend (&newfacet->ridges, ridge); + qh_setappend(&newfacet->ridges, ridge); numold++; /* already set by qh_mergecycle_neighbors */ continue; }else { - fprintf (qh ferr, "qhull internal error (qh_mergecycle_ridges): bad ridge r%d\n", ridge->id); - qh_errexit (qh_ERRqhull, NULL, ridge); + 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, sizeof(ridgeT), freelistp); numold++; }else if (neighbor->visitid == samevisitid) { - qh_setdel (neighbor->ridges, ridge); + qh_setdel(neighbor->ridges, ridge); qh_setfree(&(ridge->vertices)); qh_memfree_(ridge, sizeof(ridgeT), freelistp); numold++; }else { - qh_setappend (&newfacet->ridges, ridge); + qh_setappend(&newfacet->ridges, ridge); numold++; } } if (same->ridges) - qh_settruncate (same->ridges, 0); + 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, + ridge->vertices= qh_setnew_delnthsorted(same->vertices, qh hull_dim, neighbor_i, 0); toporient= same->toporient ^ (neighbor_i & 0x1); if (toporient) { @@ -2145,7 +2149,7 @@ void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) { } } - trace2((qh ferr, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n", + trace2((qh ferr, 2033, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n", numold, numnew)); } /* mergecycle_ridges */ @@ -2174,37 +2178,37 @@ void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) { delete it from newfacet add it to qh.del_vertices for later deletion */ -void qh_mergecycle_vneighbors (facetT *samecycle, facetT *newfacet) { +void qh_mergecycle_vneighbors(facetT *samecycle, facetT *newfacet) { facetT *neighbor, **neighborp; unsigned int mergeid; vertexT *vertex, **vertexp, *apex; setT *vertices; - trace4((qh ferr, "qh_mergecycle_vneighbors: update vertex neighbors for newfacet\n")); + 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 */ + vertices= qh_basevertices(samecycle); /* temp */ apex= SETfirstt_(samecycle->vertices, vertexT); - qh_setappend (&vertices, apex); + 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); + qh_setcompact(vertex->neighbors); + qh_setappend(&vertex->neighbors, newfacet); if (!SETsecond_(vertex->neighbors)) { zinc_(Zcyclevertex); - trace2((qh ferr, "qh_mergecycle_vneighbors: deleted v%d when merging cycle f%d into f%d\n", + 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); + qh_setdelsorted(newfacet->vertices, vertex); vertex->deleted= True; - qh_setappend (&qh del_vertices, vertex); + qh_setappend(&qh del_vertices, vertex); } } - qh_settempfree (&vertices); - trace3((qh ferr, "qh_mergecycle_vneighbors: merged vertices from cycle f%d into f%d\n", + 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 */ @@ -2233,7 +2237,7 @@ void qh_mergecycle_vneighbors (facetT *samecycle, facetT *newfacet) { adds neighboring facets to facet_mergeset if redundant or degenerate notes: - mindist/maxdist may be NULL + mindist/maxdist may be NULL (only if both NULL) traces merge if fmax_(maxdist,-mindist) > TRACEdist see: @@ -2266,7 +2270,7 @@ void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdis if (facet1->tricoplanar || facet2->tricoplanar) { if (!qh TRInormals) { - fprintf (qh ferr, "qh_mergefacet: does not work for tricoplanar facets. Use option 'Q11'\n"); + 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) { @@ -2285,13 +2289,13 @@ void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdis tracerestore= 0; qh IStracing= qh TRACElevel; traceonce= True; - fprintf (qh ferr, "qh_mergefacet: ========= trace wide merge #%d (%2.2g) for f%d into f%d, last point was p%d\n", zzval_(Ztotmerge), + 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; - fprintf (qh ferr, "qh_mergefacet: ========= trace merge #%d involving f%d, furthest is p%d\n", + 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); } } @@ -2303,22 +2307,22 @@ void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdis mergemin= *mindist; mergemax= *maxdist; } - fprintf (qh ferr, "qh_mergefacet: #%d merge f%d into f%d, mindist= %2.2g, maxdist= %2.2g\n", + 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) { - fprintf (qh ferr, "qhull internal error (qh_mergefacet): either f%d and f%d are the same or one is a visible facet\n", + 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) { - fprintf(qh ferr, "\n\ + 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) - fprintf(qh ferr, "Option 'Qx' may avoid this problem.\n"); + qh_fprintf(qh ferr, 8079, "Option 'Qx' may avoid this problem.\n"); qh_errexit(qh_ERRinput, NULL, NULL); } if (!qh VERTEXneighbors) @@ -2326,7 +2330,7 @@ too strong.\n", qh hull_dim+1); qh_makeridges(facet1); qh_makeridges(facet2); if (qh IStracing >=4) - qh_errprint ("MERGING", facet1, facet2, NULL, NULL); + qh_errprint("MERGING", facet1, facet2, NULL, NULL); if (mindist) { maximize_(qh max_outside, *maxdist); maximize_(qh max_vertex, *maxdist); @@ -2348,8 +2352,8 @@ too strong.\n", qh hull_dim+1); 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); + if (qh hull_dim > 2 && qh_setsize(facet1->vertices) == qh hull_dim) + qh_mergesimplex(facet1, facet2, mergeapex); else { qh vertex_visit++; FOREACHvertex_(facet2->vertices) @@ -2363,10 +2367,10 @@ too strong.\n", qh hull_dim+1); qh_mergeridges(facet1, facet2); qh_mergevertex_neighbors(facet1, facet2); if (!facet2->newfacet) - qh_newvertices (facet2->vertices); + qh_newvertices(facet2->vertices); } if (!mergeapex) - qh_degen_redundant_neighbors (facet2, facet1); + qh_degen_redundant_neighbors(facet2, facet1); if (facet2->coplanar || !facet2->newfacet) { zinc_(Zmergeintohorizon); }else if (!facet1->newfacet && facet2->newfacet) { @@ -2374,14 +2378,14 @@ too strong.\n", qh hull_dim+1); }else { zinc_(Zmergenew); } - qh_willdelete (facet1, facet2); + 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); + qh_tracemerge(facet1, facet2); if (traceonce) { - fprintf (qh ferr, "qh_mergefacet: end of wide tracing\n"); + qh_fprintf(qh ferr, 8080, "qh_mergefacet: end of wide tracing\n"); qh IStracing= tracerestore; } } /* mergefacet */ @@ -2410,7 +2414,7 @@ too strong.\n", qh hull_dim+1); set new vertices and neighbors and adjust orientation make ridges for new neighbor if needed */ -void qh_mergefacet2d (facetT *facet1, facetT *facet2) { +void qh_mergefacet2d(facetT *facet1, facetT *facet2) { vertexT *vertex1A, *vertex1B, *vertex2A, *vertex2B, *vertexA, *vertexB; facetT *neighbor1A, *neighbor1B, *neighbor2A, *neighbor2B, *neighborA, *neighborB; @@ -2459,9 +2463,9 @@ void qh_mergefacet2d (facetT *facet1, facetT *facet2) { SETfirst_(facet2->neighbors)= neighborB; SETsecond_(facet2->neighbors)= neighborA; } - qh_makeridges (neighborB); + qh_makeridges(neighborB); qh_setreplace(neighborB->neighbors, facet1, facet2); - trace4((qh ferr, "qh_mergefacet2d: merged v%d and neighbor f%d of f%d into f%d\n", + 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 */ @@ -2488,7 +2492,7 @@ void qh_mergefacet2d (facetT *facet1, facetT *facet2) { void qh_mergeneighbors(facetT *facet1, facetT *facet2) { facetT *neighbor, **neighborp; - trace4((qh ferr, "qh_mergeneighbors: merge neighbors of f%d and f%d\n", + trace4((qh ferr, 4037, "qh_mergeneighbors: merge neighbors of f%d and f%d\n", facet1->id, facet2->id)); qh visit_id++; FOREACHneighbor_(facet2) { @@ -2497,9 +2501,9 @@ void qh_mergeneighbors(facetT *facet1, facetT *facet2) { FOREACHneighbor_(facet1) { if (neighbor->visitid == qh visit_id) { if (neighbor->simplicial) /* is degen, needs ridges */ - qh_makeridges (neighbor); + qh_makeridges(neighbor); if (SETfirstt_(neighbor->neighbors, facetT) != facet1) /*keep newfacet->horizon*/ - qh_setdel (neighbor->neighbors, facet1); + qh_setdel(neighbor->neighbors, facet1); else { qh_setdel(neighbor->neighbors, facet2); qh_setreplace(neighbor->neighbors, facet1, facet2); @@ -2537,7 +2541,7 @@ void qh_mergeridges(facetT *facet1, facetT *facet2) { ridgeT *ridge, **ridgep; vertexT *vertex, **vertexp; - trace4((qh ferr, "qh_mergeridges: merge ridges of f%d and f%d\n", + 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)) { @@ -2609,10 +2613,10 @@ void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) { if (mergeapex) { if (!facet2->newfacet) - qh_newvertices (facet2->vertices); /* apex is new */ + 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 */ + qh_setaddnth(&facet2->vertices, 0, apex); /* apex has last id */ else issubset= True; }else { @@ -2633,7 +2637,7 @@ void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) { break; /* must occur */ } apex= vertex; - trace4((qh ferr, "qh_mergesimplex: merge apex v%d of f%d into facet f%d\n", + 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) { @@ -2644,26 +2648,26 @@ void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) { } } if (!issubset) - qh_setaddnth (&facet2->vertices, vertex_i, apex); + qh_setaddnth(&facet2->vertices, vertex_i, apex); if (!facet2->newfacet) - qh_newvertices (facet2->vertices); + qh_newvertices(facet2->vertices); else if (!apex->newlist) { - qh_removevertex (apex); - qh_appendvertex (apex); + qh_removevertex(apex); + qh_appendvertex(apex); } } - trace4((qh ferr, "qh_mergesimplex: update vertex neighbors of f%d\n", + 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); + qh_setreplace(vertex->neighbors, facet1, facet2); else { - qh_setdel (vertex->neighbors, facet1); + qh_setdel(vertex->neighbors, facet1); if (!SETsecond_(vertex->neighbors)) - qh_mergevertex_del (vertex, facet1, facet2); + qh_mergevertex_del(vertex, facet1, facet2); } } - trace4((qh ferr, "qh_mergesimplex: merge ridges and neighbors of f%d into f%d\n", + 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) @@ -2671,21 +2675,21 @@ void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) { FOREACHridge_(facet1->ridges) { otherfacet= otherfacet_(ridge, facet1); if (otherfacet == facet2) { - qh_setdel (facet2->ridges, ridge); + qh_setdel(facet2->ridges, ridge); qh_setfree(&(ridge->vertices)); - qh_memfree (ridge, sizeof(ridgeT)); - qh_setdel (facet2->neighbors, facet1); + qh_memfree(ridge, sizeof(ridgeT)); + qh_setdel(facet2->neighbors, facet1); }else { - qh_setappend (&facet2->ridges, ridge); + qh_setappend(&facet2->ridges, ridge); if (otherfacet->visitid != qh visit_id) { - qh_setappend (&facet2->neighbors, otherfacet); - qh_setreplace (otherfacet->neighbors, facet1, facet2); + 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); + qh_makeridges(otherfacet); if (SETfirstt_(otherfacet->neighbors, facetT) != facet1) - qh_setdel (otherfacet->neighbors, facet1); + qh_setdel(otherfacet->neighbors, facet1); else { /*keep newfacet->neighbors->horizon*/ qh_setdel(otherfacet->neighbors, facet2); qh_setreplace(otherfacet->neighbors, facet1, facet2); @@ -2698,7 +2702,7 @@ void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) { } } SETfirst_(facet1->ridges)= NULL; /* it will be deleted */ - trace3((qh ferr, "qh_mergesimplex: merged simplex f%d apex v%d into facet f%d\n", + 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 */ @@ -2712,14 +2716,14 @@ void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) { deletes vertex from facet2 adds vertex to qh.del_vertices for later deletion */ -void qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2) { +void qh_mergevertex_del(vertexT *vertex, facetT *facet1, facetT *facet2) { zinc_(Zmergevertex); - trace2((qh ferr, "qh_mergevertex_del: deleted v%d when merging f%d into f%d\n", + 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); + qh_setdelsorted(facet2->vertices, vertex); vertex->deleted= True; - qh_setappend (&qh del_vertices, vertex); + qh_setappend(&qh del_vertices, vertex); } /* mergevertex_del */ /*-<a href="qh-merge.htm#TOC" @@ -2741,12 +2745,12 @@ void qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2) { void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2) { vertexT *vertex, **vertexp; - trace4((qh ferr, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n", + trace4((qh ferr, 4042, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n", facet1->id, facet2->id)); if (qh tracevertex) { - fprintf (qh ferr, "qh_mergevertex_neighbors: of f%d and f%d at furthest p%d f0= %p\n", + 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); + qh_errprint("TRACE", NULL, NULL, NULL, qh tracevertex); } FOREACHvertex_(facet1->vertices) { if (vertex->visitid != qh vertex_visit) @@ -2754,11 +2758,11 @@ void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2) { else { qh_setdel(vertex->neighbors, facet1); if (!SETsecond_(vertex->neighbors)) - qh_mergevertex_del (vertex, facet1, facet2); + qh_mergevertex_del(vertex, facet1, facet2); } } if (qh tracevertex) - qh_errprint ("TRACE", NULL, NULL, NULL, qh tracevertex); + qh_errprint("TRACE", NULL, NULL, NULL, qh tracevertex); } /* mergevertex_neighbors */ @@ -2781,28 +2785,28 @@ void qh_mergevertices(setT *vertices1, setT **vertices2) { setT *mergedvertices; vertexT *vertex, **vertexp, **vertex2= SETaddr_(*vertices2, vertexT); - mergedvertices= qh_settemp (newsize); + mergedvertices= qh_settemp(newsize); FOREACHvertex_(vertices1) { if (!*vertex2 || vertex->id > (*vertex2)->id) - qh_setappend (&mergedvertices, vertex); + qh_setappend(&mergedvertices, vertex); else { while (*vertex2 && (*vertex2)->id > vertex->id) - qh_setappend (&mergedvertices, *vertex2++); + qh_setappend(&mergedvertices, *vertex2++); if (!*vertex2 || (*vertex2)->id < vertex->id) - qh_setappend (&mergedvertices, vertex); + qh_setappend(&mergedvertices, vertex); else - qh_setappend (&mergedvertices, *vertex2++); + qh_setappend(&mergedvertices, *vertex2++); } } while (*vertex2) - qh_setappend (&mergedvertices, *vertex2++); - if (newsize < qh_setsize (mergedvertices)) { - fprintf (qh ferr, "qhull internal error (qh_mergevertices): facets did not share a ridge\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_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 (); + qh_settemppop(); } /* mergevertices */ @@ -2829,7 +2833,7 @@ void qh_mergevertices(setT *vertices1, setT **vertices2) { return NULL if empty return the intersection set */ -setT *qh_neighbor_intersections (vertexT *vertex) { +setT *qh_neighbor_intersections(vertexT *vertex) { facetT *neighbor, **neighborp, *neighborA, *neighborB; setT *intersect; int neighbor_i, neighbor_n; @@ -2844,24 +2848,24 @@ setT *qh_neighbor_intersections (vertexT *vertex) { if (!neighborA) return NULL; if (!neighborB) - intersect= qh_setcopy (neighborA->vertices, 0); + intersect= qh_setcopy(neighborA->vertices, 0); else - intersect= qh_vertexintersect_new (neighborA->vertices, neighborB->vertices); - qh_settemppush (intersect); - qh_setdelsorted (intersect, vertex); + 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); + qh_vertexintersect(&intersect, neighbor->vertices); if (!SETfirst_(intersect)) { zinc_(Zintersectfail); - qh_settempfree (&intersect); + qh_settempfree(&intersect); return NULL; } } } - trace3((qh ferr, "qh_neighbor_intersections: %d vertices in neighbor intersection of v%d\n", - qh_setsize (intersect), vertex->id)); + 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 */ @@ -2875,13 +2879,13 @@ setT *qh_neighbor_intersections (vertexT *vertex) { vertices on qh.newvertex_list vertex->newlist set */ -void qh_newvertices (setT *vertices) { +void qh_newvertices(setT *vertices) { vertexT *vertex, **vertexp; FOREACHvertex_(vertices) { if (!vertex->newlist) { - qh_removevertex (vertex); - qh_appendvertex (vertex); + qh_removevertex(vertex); + qh_appendvertex(vertex); } } } /* newvertices */ @@ -2913,7 +2917,7 @@ void qh_newvertices (setT *vertices) { rename vertex if it is shared remove delridge flag from new vertices */ -boolT qh_reducevertices (void) { +boolT qh_reducevertices(void) { int numshare=0, numrename= 0; boolT degenredun= False; facetT *newfacet; @@ -2928,7 +2932,7 @@ boolT qh_reducevertices (void) { if (newfacet->newmerge) { if (!qh MERGEvertices) newfacet->newmerge= False; - qh_remove_extravertices (newfacet); + qh_remove_extravertices(newfacet); } } if (!qh MERGEvertices) @@ -2938,7 +2942,7 @@ boolT qh_reducevertices (void) { newfacet->newmerge= False; FOREACHvertex_(newfacet->vertices) { if (vertex->delridge) { - if (qh_rename_sharedvertex (vertex, newfacet)) { + if (qh_rename_sharedvertex(vertex, newfacet)) { numshare++; vertexp--; /* repeat since deleted vertex */ } @@ -2949,7 +2953,7 @@ boolT qh_reducevertices (void) { FORALLvertex_(qh newvertex_list) { if (vertex->delridge && !vertex->deleted) { vertex->delridge= False; - if (qh hull_dim >= 4 && qh_redundant_vertex (vertex)) { + if (qh hull_dim >= 4 && qh_redundant_vertex(vertex)) { numrename++; if (qh_merge_degenredundant()) { degenredun= True; @@ -2958,7 +2962,7 @@ boolT qh_reducevertices (void) { } } } - trace1((qh ferr, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n", + trace1((qh ferr, 1014, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n", numshare, numrename, degenredun)); return degenredun; } /* reducevertices */ @@ -2972,7 +2976,7 @@ boolT qh_reducevertices (void) { returns: returns true if find a redundant vertex - deletes vertex (vertex->deleted) + deletes vertex(vertex->deleted) notes: only needed if vertex->delridge and hull_dim >= 4 @@ -2985,17 +2989,17 @@ boolT qh_reducevertices (void) { 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 *qh_redundant_vertex(vertexT *vertex) { vertexT *newvertex= NULL; setT *vertices, *ridges; - trace3((qh ferr, "qh_redundant_vertex: check if v%d can be renamed\n", vertex->id)); - if ((vertices= qh_neighbor_intersections (vertex))) { - ridges= qh_vertexridges (vertex); - if ((newvertex= qh_find_newvertex (vertex, vertices, ridges))) - qh_renamevertex (vertex, newvertex, ridges, NULL, NULL); - qh_settempfree (&ridges); - qh_settempfree (&vertices); + 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 */ @@ -3017,12 +3021,12 @@ vertexT *qh_redundant_vertex (vertexT *vertex) { unless vertex in another facet add vertex to qh.del_vertices for later deletion */ -boolT qh_remove_extravertices (facetT *facet) { +boolT qh_remove_extravertices(facetT *facet) { ridgeT *ridge, **ridgep; vertexT *vertex, **vertexp; boolT foundrem= False; - trace4((qh ferr, "qh_remove_extravertices: test f%d for extra vertices\n", + trace4((qh ferr, 4043, "qh_remove_extravertices: test f%d for extra vertices\n", facet->id)); FOREACHvertex_(facet->vertices) vertex->seen= False; @@ -3034,15 +3038,15 @@ boolT qh_remove_extravertices (facetT *facet) { if (!vertex->seen) { foundrem= True; zinc_(Zremvertex); - qh_setdelsorted (facet->vertices, vertex); - qh_setdel (vertex->neighbors, facet); - if (!qh_setsize (vertex->neighbors)) { + qh_setdelsorted(facet->vertices, vertex); + qh_setdel(vertex->neighbors, facet); + if (!qh_setsize(vertex->neighbors)) { vertex->deleted= True; - qh_setappend (&qh del_vertices, vertex); + qh_setappend(&qh del_vertices, vertex); zinc_(Zremvertexdel); - trace2((qh ferr, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id)); + trace2((qh ferr, 2036, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id)); }else - trace3((qh ferr, "qh_remove_extravertices: v%d removed from f%d because it's lost all ridges\n", vertex->id, facet->id)); + 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*/ } } @@ -3076,12 +3080,12 @@ boolT qh_remove_extravertices (facetT *facet) { if can find a new vertex in this set rename the vertex to the new vertex */ -vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet) { +vertexT *qh_rename_sharedvertex(vertexT *vertex, facetT *facet) { facetT *neighbor, **neighborp, *neighborA= NULL; setT *vertices, *ridges; vertexT *newvertex; - if (qh_setsize (vertex->neighbors) == 2) { + if (qh_setsize(vertex->neighbors) == 2) { neighborA= SETfirstt_(vertex->neighbors, facetT); if (neighborA == facet) neighborA= SETsecondt_(vertex->neighbors, facetT); @@ -3099,26 +3103,26 @@ vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet) { } } if (!neighborA) { - fprintf (qh ferr, "qhull internal error (qh_rename_sharedvertex): v%d's neighbors not in f%d\n", + 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); + 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); + ridges= qh_settemp(qh TEMPsize); neighborA->visitid= ++qh visit_id; - qh_vertexridges_facet (vertex, facet, &ridges); - trace2((qh ferr, "qh_rename_sharedvertex: p%d (v%d) is shared by f%d (%d ridges) and f%d\n", - qh_pointid(vertex->point), vertex->id, facet->id, qh_setsize (ridges), neighborA->id)); + 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); + 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 */ @@ -3144,15 +3148,15 @@ void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) facetT *temp; vertexT *vertex, **vertexp; - oldnth= qh_setindex (ridge->vertices, oldvertex); - qh_setdelnthsorted (ridge->vertices, oldnth); + oldnth= qh_setindex(ridge->vertices, oldvertex); + qh_setdelnthsorted(ridge->vertices, oldnth); FOREACHvertex_(ridge->vertices) { if (vertex == newvertex) { zinc_(Zdelridge); if (ridge->nonconvex) /* only one ridge has nonconvex set */ - qh_copynonconvex (ridge); - qh_delridge (ridge); - trace2((qh ferr, "qh_renameridgevertex: ridge r%d deleted. It contained both v%d and v%d\n", + 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; } @@ -3162,7 +3166,7 @@ void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) } qh_setaddnth(&ridge->vertices, nth, newvertex); if (abs(oldnth - nth)%2) { - trace3((qh ferr, "qh_renameridgevertex: swapped the top and bottom of ridge r%d\n", + 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; @@ -3210,39 +3214,39 @@ void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges, facet newvertex->id == qh tracevertex_id) istrace= True; FOREACHridge_(ridges) - qh_renameridgevertex (ridge, oldvertex, newvertex); + qh_renameridgevertex(ridge, oldvertex, newvertex); if (!oldfacet) { zinc_(Zrenameall); if (istrace) - fprintf (qh ferr, "qh_renamevertex: renamed v%d to v%d in several facets\n", + 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)) + 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); + qh_setappend(&qh del_vertices, oldvertex); } - }else if (qh_setsize (oldvertex->neighbors) == 2) { + }else if (qh_setsize(oldvertex->neighbors) == 2) { zinc_(Zrenameshare); if (istrace) - fprintf (qh ferr, "qh_renamevertex: renamed v%d to v%d in oldfacet f%d\n", + 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); + qh_setdelsorted(neighbor->vertices, oldvertex); oldvertex->deleted= True; - qh_setappend (&qh del_vertices, oldvertex); + qh_setappend(&qh del_vertices, oldvertex); }else { zinc_(Zrenamepinch); if (istrace || qh IStracing) - fprintf (qh ferr, "qh_renamevertex: renamed pinched v%d to v%d between f%d and f%d\n", + 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); + qh_setdelsorted(oldfacet->vertices, oldvertex); + qh_setdel(oldvertex->neighbors, oldfacet); + qh_remove_extravertices(neighborA); } } /* renamevertex */ @@ -3281,7 +3285,7 @@ void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges, facet get angle if needed append concave or coplanar merge to qh.mergeset */ -boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) { +boolT qh_test_appendmerge(facetT *facet, facetT *neighbor) { realT dist, dist2= -REALmax, angle= -REALmax; boolT isconcave= False, iscoplanar= False, okangle= False; @@ -3293,14 +3297,14 @@ boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) { if (angle > qh cos_max) { zinc_(Zcoplanarangle); qh_appendmergeset(facet, neighbor, MRGanglecoplanar, &angle); - trace2((qh ferr, "qh_test_appendmerge: coplanar angle %4.4g between f%d and f%d\n", + 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); + facet->center= qh_getcentrum(facet); zzinc_(Zcentrumtests); qh_distplane(facet->center, neighbor, &dist); if (dist > qh centrum_radius) @@ -3309,7 +3313,7 @@ boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) { if (dist > -qh centrum_radius) iscoplanar= True; if (!neighbor->center) - neighbor->center= qh_getcentrum (neighbor); + neighbor->center= qh_getcentrum(neighbor); zzinc_(Zcentrumtests); qh_distplane(neighbor->center, facet, &dist2); if (dist2 > qh centrum_radius) @@ -3328,12 +3332,12 @@ boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) { if (qh ANGLEmerge) angle += qh_ANGLEconcave + 0.5; qh_appendmergeset(facet, neighbor, MRGconcave, &angle); - trace0((qh ferr, "qh_test_appendmerge: concave f%d to f%d dist %4.4g and reverse dist %4.4g angle %4.4g during p%d\n", + 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, "qh_test_appendmerge: coplanar f%d to f%d dist %4.4g, reverse dist %4.4g angle %4.4g\n", + 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; @@ -3364,12 +3368,12 @@ boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) { for each unvisited facet neighbor of the vertex test new facet and neighbor for convexity */ -boolT qh_test_vneighbors (void /* qh newfacet_list */) { +boolT qh_test_vneighbors(void /* qh newfacet_list */) { facetT *newfacet, *neighbor, **neighborp; vertexT *vertex, **vertexp; int nummerges= 0; - trace1((qh ferr, "qh_test_vneighbors: testing vertex neighbors for convexity\n")); + trace1((qh ferr, 1015, "qh_test_vneighbors: testing vertex neighbors for convexity\n")); if (!qh VERTEXneighbors) qh_vertexneighbors(); FORALLnew_facets @@ -3383,13 +3387,13 @@ boolT qh_test_vneighbors (void /* qh newfacet_list */) { FOREACHneighbor_(vertex) { if (neighbor->seen || neighbor->visitid == qh visit_id) continue; - if (qh_test_appendmerge (newfacet, neighbor)) + if (qh_test_appendmerge(newfacet, neighbor)) nummerges++; } } } zadd_(Ztestvneighbor, nummerges); - trace1((qh ferr, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n", + trace1((qh ferr, 1016, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n", nummerges)); return (nummerges > 0); } /* test_vneighbors */ @@ -3400,35 +3404,35 @@ boolT qh_test_vneighbors (void /* qh newfacet_list */) { qh_tracemerge( facet1, facet2 ) print trace message after merge */ -void qh_tracemerge (facetT *facet1, facetT *facet2) { +void qh_tracemerge(facetT *facet1, facetT *facet2) { boolT waserror= False; #ifndef qh_NOtrace if (qh IStracing >= 4) - qh_errprint ("MERGED", facet2, NULL, NULL, NULL); + qh_errprint("MERGED", facet2, NULL, NULL, NULL); if (facet2 == qh tracefacet || (qh tracevertex && qh tracevertex->newlist)) { - fprintf (qh ferr, "qh_tracemerge: trace facet and vertex after merge of f%d and f%d, furthest p%d\n", facet1->id, facet2->id, qh furthest_id); + 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_errprint("TRACE", qh tracefacet, (qh tracevertex && qh tracevertex->neighbors) ? SETfirstt_(qh tracevertex->neighbors, facetT) : NULL, NULL, qh tracevertex); } if (qh tracevertex) { if (qh tracevertex->deleted) - fprintf (qh ferr, "qh_tracemerge: trace vertex deleted at furthest p%d\n", + qh_fprintf(qh ferr, 8086, "qh_tracemerge: trace vertex deleted at furthest p%d\n", qh furthest_id); else - qh_checkvertex (qh tracevertex); + qh_checkvertex(qh tracevertex); } if (qh tracefacet) { - qh_checkfacet (qh tracefacet, True, &waserror); + qh_checkfacet(qh tracefacet, True, &waserror); if (waserror) - qh_errexit (qh_ERRqhull, qh tracefacet, NULL); + 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); + qh_checkfacet(facet2, True, &waserror); if (waserror) qh_errexit(qh_ERRqhull, NULL, NULL); } @@ -3449,24 +3453,24 @@ void qh_tracemerge (facetT *facet1, facetT *facet2) { see: qh_buildtracing() */ -void qh_tracemerging (void) { +void qh_tracemerging(void) { realT cpu; int total; time_t timedata; struct tm *tp; qh mergereport= zzval_(Ztotmerge); - time (&timedata); - tp= localtime (&timedata); + time(&timedata); + tp= localtime(&timedata); cpu= qh_CPUclock; cpu /= qh_SECticks; total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot); - fprintf (qh ferr, "\n\ + 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)); + qh num_vertices-qh_setsize(qh del_vertices)); } /* tracemerging */ /*-<a href="qh-merge.htm#TOC" @@ -3491,7 +3495,7 @@ At %d:%d:%d & %2.5g CPU secs, qhull has merged %d facets. The hull\n\ clear facet2->center to recompute centrum later clear ridge->tested for facet2's ridges */ -void qh_updatetested (facetT *facet1, facetT *facet2) { +void qh_updatetested(facetT *facet1, facetT *facet2) { ridgeT *ridge, **ridgep; int size; @@ -3500,7 +3504,7 @@ void qh_updatetested (facetT *facet1, facetT *facet2) { ridge->tested= False; if (!facet2->center) return; - size= qh_setsize (facet2->vertices); + size= qh_setsize(facet2->vertices); if (!facet2->keepcentrum) { if (size > qh hull_dim + qh_MAXnewcentrum) { facet2->keepcentrum= True; @@ -3512,7 +3516,7 @@ void qh_updatetested (facetT *facet1, facetT *facet2) { facet2->keepcentrum= False; /* if many merges need to recompute centrum */ } if (!facet2->keepcentrum) { - qh_memfree (facet2->center, qh normal_size); + qh_memfree(facet2->center, qh normal_size); facet2->center= NULL; FOREACHridge_(facet2->ridges) ridge->tested= False; @@ -3534,9 +3538,9 @@ void qh_updatetested (facetT *facet1, facetT *facet2) { for each neighbor of vertex add ridges that include the vertex to ridges */ -setT *qh_vertexridges (vertexT *vertex) { +setT *qh_vertexridges(vertexT *vertex) { facetT *neighbor, **neighborp; - setT *ridges= qh_settemp (qh TEMPsize); + setT *ridges= qh_settemp(qh TEMPsize); int size; qh visit_id++; @@ -3544,14 +3548,14 @@ setT *qh_vertexridges (vertexT *vertex) { neighbor->visitid= qh visit_id; FOREACHneighbor_(vertex) { if (*neighborp) /* no new ridges in last neighbor */ - qh_vertexridges_facet (vertex, neighbor, &ridges); + qh_vertexridges_facet(vertex, neighbor, &ridges); } if (qh PRINTstatistics || qh IStracing) { - size= qh_setsize (ridges); + size= qh_setsize(ridges); zinc_(Zvertexridge); zadd_(Zvertexridgetot, size); zmax_(Zvertexridgemax, size); - trace3((qh ferr, "qh_vertexridges: found %d ridges for v%d\n", + trace3((qh ferr, 3011, "qh_vertexridges: found %d ridges for v%d\n", size, vertex->id)); } return ridges; @@ -3575,15 +3579,15 @@ setT *qh_vertexridges (vertexT *vertex) { append ridge to vertex mark facet processed */ -void qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges) { +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); + && qh_setin(ridge->vertices, vertex)) + qh_setappend(ridges, ridge); } facet->visitid= qh visit_id-1; } /* vertexridges_facet */ @@ -3598,22 +3602,22 @@ void qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges) { returns: bumps qh.num_visible */ -void qh_willdelete (facetT *facet, facetT *replace) { +void qh_willdelete(facetT *facet, facetT *replace) { qh_removefacet(facet); - qh_prependfacet (facet, &qh visible_list); + 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_premerge(vertexT *apex, realT maxcentrum, realT maxangle) { } -void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, +void qh_postmerge(char *reason, realT maxcentrum, realT maxangle, boolT vneighbors) { } -boolT qh_checkzero (boolT testall) { +boolT qh_checkzero(boolT testall) { } #endif /* qh_NOmerge */ diff --git a/src/merge.h b/src/merge.h index 5dc8ac1..d8cd71b 100644 --- a/src/merge.h +++ b/src/merge.h @@ -6,12 +6,16 @@ see qh-merge.htm and merge.c - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/merge.h#16 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ #ifndef qhDEFmerge #define qhDEFmerge 1 +#include "qhulllib.h" + /*============ -constants- ==============*/ @@ -58,7 +62,7 @@ typedef enum { /* in sort order for facet_mergeset */ MRGflip, /* flipped facet. facet1 == facet2 */ MRGridge, /* duplicate ridge (qh_MERGEridge) */ /* degen and redundant go onto degen_mergeset */ - MRGdegen, /* degenerate facet (not enough neighbors) facet1 == facet2 */ + MRGdegen, /* degenerate facet (!enough neighbors) facet1 == facet2 */ MRGredundant, /* redundant facet (vertex subset) */ /* merge_degenredundant assumes degen < redundant */ MRGmirror, /* mirror facet from qh_triangulate */ @@ -109,66 +113,66 @@ struct mergeT { /* initialize in qh_appendmergeset */ /*============ prototypes in alphabetical order after pre/postmerge =======*/ -void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle); -void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, +void qh_premerge(vertexT *apex, realT maxcentrum, realT maxangle); +void qh_postmerge(char *reason, realT maxcentrum, realT maxangle, boolT vneighbors); -void qh_all_merges (boolT othermerge, boolT vneighbors); +void qh_all_merges(boolT othermerge, boolT vneighbors); void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle); setT *qh_basevertices( facetT *samecycle); -void qh_checkconnect (void /* qh new_facets */); -boolT qh_checkzero (boolT testall); +void qh_checkconnect(void /* qh new_facets */); +boolT qh_checkzero(boolT testall); int qh_compareangle(const void *p1, const void *p2); int qh_comparemerge(const void *p1, const void *p2); -int qh_comparevisit (const void *p1, const void *p2); -void qh_copynonconvex (ridgeT *atridge); -void qh_degen_redundant_facet (facetT *facet); -void qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet); -vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges); -void qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor, +int qh_comparevisit(const void *p1, const void *p2); +void qh_copynonconvex(ridgeT *atridge); +void qh_degen_redundant_facet(facetT *facet); +void qh_degen_redundant_neighbors(facetT *facet, facetT *delfacet); +vertexT *qh_find_newvertex(vertexT *oldvertex, setT *vertices, setT *ridges); +void qh_findbest_test(boolT testcentrum, facetT *facet, facetT *neighbor, facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp); facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp); void qh_flippedmerges(facetT *facetlist, boolT *wasmerge); void qh_forcedmerges( boolT *wasmerge); void qh_getmergeset(facetT *facetlist); -void qh_getmergeset_initial (facetT *facetlist); -void qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex); -ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, +void qh_getmergeset_initial(facetT *facetlist); +void qh_hashridge(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex); +ridgeT *qh_hashridge_find(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *vertex, vertexT *oldvertex, int *hashslot); void qh_makeridges(facetT *facet); void qh_mark_dupridges(facetT *facetlist); -void qh_maydropneighbor (facetT *facet); -int qh_merge_degenredundant (void); +void qh_maydropneighbor(facetT *facet); +int qh_merge_degenredundant(void); void qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype); -void qh_mergecycle (facetT *samecycle, facetT *newfacet); -void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge); +void qh_mergecycle(facetT *samecycle, facetT *newfacet); +void qh_mergecycle_all(facetT *facetlist, boolT *wasmerge); void qh_mergecycle_facets( facetT *samecycle, facetT *newfacet); void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet); void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet); void qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet); void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex); -void qh_mergefacet2d (facetT *facet1, facetT *facet2); +void qh_mergefacet2d(facetT *facet1, facetT *facet2); void qh_mergeneighbors(facetT *facet1, facetT *facet2); void qh_mergeridges(facetT *facet1, facetT *facet2); void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex); -void qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2); +void qh_mergevertex_del(vertexT *vertex, facetT *facet1, facetT *facet2); void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2); void qh_mergevertices(setT *vertices1, setT **vertices); -setT *qh_neighbor_intersections (vertexT *vertex); -void qh_newvertices (setT *vertices); -boolT qh_reducevertices (void); -vertexT *qh_redundant_vertex (vertexT *vertex); -boolT qh_remove_extravertices (facetT *facet); -vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet); +setT *qh_neighbor_intersections(vertexT *vertex); +void qh_newvertices(setT *vertices); +boolT qh_reducevertices(void); +vertexT *qh_redundant_vertex(vertexT *vertex); +boolT qh_remove_extravertices(facetT *facet); +vertexT *qh_rename_sharedvertex(vertexT *vertex, facetT *facet); void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex); void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges, facetT *oldfacet, facetT *neighborA); -boolT qh_test_appendmerge (facetT *facet, facetT *neighbor); -boolT qh_test_vneighbors (void /* qh newfacet_list */); -void qh_tracemerge (facetT *facet1, facetT *facet2); -void qh_tracemerging (void); +boolT qh_test_appendmerge(facetT *facet, facetT *neighbor); +boolT qh_test_vneighbors(void /* qh newfacet_list */); +void qh_tracemerge(facetT *facet1, facetT *facet2); +void qh_tracemerging(void); void qh_updatetested( facetT *facet1, facetT *facet2); -setT *qh_vertexridges (vertexT *vertex); -void qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges); -void qh_willdelete (facetT *facet, facetT *replace); +setT *qh_vertexridges(vertexT *vertex); +void qh_vertexridges_facet(vertexT *vertex, facetT *facet, setT **ridges); +void qh_willdelete(facetT *facet, facetT *replace); #endif /* qhDEFmerge */ diff --git a/src/poly.c b/src/poly.c index 3bacbf8..2186786 100644 --- a/src/poly.c +++ b/src/poly.c @@ -4,12 +4,14 @@ poly.c implements polygons and simplices - see qh-poly.htm, poly.h and qhull.h + see qh-poly.htm, poly.h and qhulllib.h infrequent code is in poly2.c (all but top 50 and their callers 12/3/95) - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/poly.c#20 $$Change: 1095 $ + $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ */ #include "qhull_a.h" @@ -48,7 +50,7 @@ void qh_appendfacet(facetT *facet) { qh facet_list= facet; tail->previous= facet; qh num_facets++; - trace4((qh ferr, "qh_appendfacet: append f%d to facet_list\n", facet->id)); + trace4((qh ferr, 4044, "qh_appendfacet: append f%d to facet_list\n", facet->id)); } /* appendfacet */ @@ -67,7 +69,7 @@ void qh_appendfacet(facetT *facet) { assumes qh.vertex_list/vertex_tail is defined (createsimplex) */ -void qh_appendvertex (vertexT *vertex) { +void qh_appendvertex(vertexT *vertex) { vertexT *tail= qh vertex_tail; if (tail == qh newvertex_list) @@ -81,7 +83,7 @@ void qh_appendvertex (vertexT *vertex) { qh vertex_list= vertex; tail->previous= vertex; qh num_vertices++; - trace4((qh ferr, "qh_appendvertex: append v%d to vertex_list\n", vertex->id)); + trace4((qh ferr, 4045, "qh_appendvertex: append v%d to vertex_list\n", vertex->id)); } /* appendvertex */ @@ -124,12 +126,12 @@ void qh_appendvertex (vertexT *vertex) { the first ridge of the new facet is the horizon ridge link the new facet into the horizon ridge */ -void qh_attachnewfacets (void ) { +void qh_attachnewfacets(void ) { facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible; ridgeT *ridge, **ridgep; qh NEWfacets= True; - trace3((qh ferr, "qh_attachnewfacets: delete interior ridges\n")); + trace3((qh ferr, 3012, "qh_attachnewfacets: delete interior ridges\n")); qh visit_id++; FORALLvisible_facets { visible->visitid= qh visit_id; @@ -139,16 +141,16 @@ void qh_attachnewfacets (void ) { if (neighbor->visitid == qh visit_id || (!neighbor->visible && neighbor->simplicial)) { if (!neighbor->visible) /* delete ridge for simplicial horizon */ - qh_setdel (neighbor->ridges, ridge); - qh_setfree (&(ridge->vertices)); /* delete on 2nd visit */ - qh_memfree (ridge, sizeof(ridgeT)); + qh_setdel(neighbor->ridges, ridge); + qh_setfree(&(ridge->vertices)); /* delete on 2nd visit */ + qh_memfree(ridge, sizeof(ridgeT)); } } SETfirst_(visible->ridges)= NULL; } SETfirst_(visible->neighbors)= NULL; } - trace1((qh ferr, "qh_attachnewfacets: attach horizon facets to new facets\n")); + trace1((qh ferr, 1017, "qh_attachnewfacets: attach horizon facets to new facets\n")); FORALLnew_facets { horizon= SETfirstt_(newfacet->neighbors, facetT); if (horizon->simplicial) { @@ -156,7 +158,7 @@ void qh_attachnewfacets (void ) { FOREACHneighbor_(horizon) { /* may have more than one horizon ridge */ if (neighbor->visible) { if (visible) { - if (qh_setequal_skip (newfacet->vertices, 0, horizon->vertices, + if (qh_setequal_skip(newfacet->vertices, 0, horizon->vertices, SETindex_(horizon->neighbors, neighbor))) { visible= neighbor; break; @@ -167,9 +169,9 @@ void qh_attachnewfacets (void ) { } if (visible) { visible->f.replace= newfacet; - qh_setreplace (horizon->neighbors, visible, newfacet); + qh_setreplace(horizon->neighbors, visible, newfacet); }else { - fprintf (qh ferr, "qhull internal error (qh_attachnewfacets): couldn't find visible facet for horizon f%d of newfacet f%d\n", + 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); } @@ -177,12 +179,12 @@ void qh_attachnewfacets (void ) { FOREACHneighbor_(horizon) { /* may hold for many new facets */ if (neighbor->visible) { neighbor->f.replace= newfacet; - qh_setdelnth (horizon->neighbors, + qh_setdelnth(horizon->neighbors, SETindex_(horizon->neighbors, neighbor)); neighborp--; /* repeat */ } } - qh_setappend (&horizon->neighbors, newfacet); + qh_setappend(&horizon->neighbors, newfacet); ridge= SETfirstt_(newfacet->ridges, ridgeT); if (ridge->top == horizon) ridge->bottom= newfacet; @@ -213,7 +215,7 @@ void qh_attachnewfacets (void ) { False if it flipped orientation (sets facet->flipped) distance if non-NULL */ -boolT qh_checkflipped (facetT *facet, realT *distp, boolT allerror) { +boolT qh_checkflipped(facetT *facet, realT *distp, boolT allerror) { realT dist; if (facet->flipped && !distp) @@ -225,9 +227,9 @@ boolT qh_checkflipped (facetT *facet, realT *distp, boolT allerror) { if ((allerror && dist > -qh DISTround)|| (!allerror && dist >= 0.0)) { facet->flipped= True; zzinc_(Zflippedfacets); - trace0((qh ferr, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n", + 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"); + qh_precision("flipped facet"); return False; } return True; @@ -245,7 +247,7 @@ boolT qh_checkflipped (facetT *facet, realT *distp, boolT allerror) { void qh_delfacet(facetT *facet) { void **freelistp; /* used !qh_NOmem */ - trace4((qh ferr, "qh_delfacet: delete f%d\n", facet->id)); + trace4((qh ferr, 4046, "qh_delfacet: delete f%d\n", facet->id)); if (facet == qh tracefacet) qh tracefacet= NULL; if (facet == qh GOODclosest) @@ -287,12 +289,12 @@ void qh_delfacet(facetT *facet) { new facets in qh.newfacet_list uses qh.visit_id; */ -void qh_deletevisible (void /*qh visible_list*/) { +void qh_deletevisible(void /*qh visible_list*/) { facetT *visible, *nextfacet; vertexT *vertex, **vertexp; int numvisible= 0, numdel= qh_setsize(qh del_vertices); - trace1((qh ferr, "qh_deletevisible: delete %d visible facets and %d vertices\n", + 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 */ @@ -301,9 +303,9 @@ void qh_deletevisible (void /*qh visible_list*/) { qh_delfacet(visible); } if (numvisible != qh num_visible) { - fprintf (qh ferr, "qhull internal error (qh_deletevisible): qh num_visible %d is not number of visible facets %d\n", + qh_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_errexit(qh_ERRqhull, NULL, NULL); } qh num_visible= 0; zadd_(Zvisfacettot, numvisible); @@ -311,8 +313,8 @@ void qh_deletevisible (void /*qh visible_list*/) { zzadd_(Zdelvertextot, numdel); zmax_(Zdelvertexmax, numdel); FOREACHvertex_(qh del_vertices) - qh_delvertex (vertex); - qh_settruncate (qh del_vertices, 0); + qh_delvertex(vertex); + qh_settruncate(qh del_vertices, 0); } /* deletevisible */ /*-<a href="qh-poly.htm#TOC" @@ -338,7 +340,7 @@ void qh_deletevisible (void /*qh visible_list*/) { locate skipped vertex by scanning facet B's neighbors intersect the vertex sets */ -setT *qh_facetintersect (facetT *facetA, facetT *facetB, +setT *qh_facetintersect(facetT *facetA, facetT *facetB, int *skipA,int *skipB, int prepend) { setT *intersect; int dim= qh hull_dim, i, j; @@ -354,7 +356,7 @@ setT *qh_facetintersect (facetT *facetA, facetT *facetB, else if (facetB == *neighborsA++) *skipA= 2; else { - for (i= 3; i < dim; i++) { + for (i=3; i < dim; i++) { if (facetB == *neighborsA++) { *skipA= i; break; @@ -368,7 +370,7 @@ setT *qh_facetintersect (facetT *facetA, facetT *facetB, else if (facetA == *neighborsB++) *skipB= 2; else { - for (j= 3; j < dim; j++) { + for (j=3; j < dim; j++) { if (facetA == *neighborsB++) { *skipB= j; break; @@ -376,12 +378,12 @@ setT *qh_facetintersect (facetT *facetA, facetT *facetB, } } if (i >= dim || j >= dim) { - fprintf (qh ferr, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n", + 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, "qh_facetintersect: f%d skip %d matches f%d skip %d\n", + 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 */ @@ -399,10 +401,14 @@ setT *qh_facetintersect (facetT *facetA, facetT *facetB, hashes memory addresses which may change over different runs of the same data using sum for hash does badly in high d */ -unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem) { +unsigned qh_gethash(int hashsize, setT *set, int size, int firstindex, void *skipelem) { void **elemp= SETelemaddr_(set, firstindex, void); ptr_intT hash = 0, elem; int i; +#ifdef _MSC_VER /* Microsoft Visual C++ -- warn about 64-bit issues */ +#pragma warning( push) /* WARN64 -- ptr_intT was defined for 64-bit issues */ +#pragma warning( disable : 4311) /* 'type cast': pointer truncation from 'void*' to 'ptr_intT' */ +#endif switch (size-firstindex) { case 1: @@ -438,12 +444,15 @@ unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *sk if (i >= 32) i -= 32; } - }while(*elemp); + }while (*elemp); break; } hash %= (ptr_intT) hashsize; /* hash= 0; for debugging purposes */ return hash; +#ifdef _MSC_VER +#pragma warning( pop) +#endif } /* gethash */ /*-<a href="qh-poly.htm#TOC" @@ -466,8 +475,8 @@ facetT *qh_makenewfacet(setT *vertices, boolT toporient,facetT *horizon) { FOREACHvertex_(vertices) { if (!vertex->newlist) { - qh_removevertex (vertex); - qh_appendvertex (vertex); + qh_removevertex(vertex); + qh_appendvertex(vertex); } } newfacet= qh_newfacet(); @@ -494,12 +503,12 @@ facetT *qh_makenewfacet(setT *vertices, boolT toporient,facetT *horizon) { notes: facet->f.samecycle is defined for facet->mergehorizon facets */ -void qh_makenewplanes (void /* newfacet_list */) { +void qh_makenewplanes(void /* newfacet_list */) { facetT *newfacet; FORALLnew_facets { if (!newfacet->mergehorizon) - qh_setfacetplane (newfacet); + qh_setfacetplane(newfacet); } if (qh JOGGLEmax < REALmax/2) minimize_(qh min_vertex, -wwval_(Wnewvertexmax)); @@ -544,7 +553,7 @@ void qh_makenewplanes (void /* newfacet_list */) { */ #ifndef qh_NOmerge -facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { +facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew) { void **freelistp; /* used !qh_NOmem */ ridgeT *ridge, **ridgep; facetT *neighbor, *newfacet= NULL, *samecycle; @@ -558,15 +567,15 @@ facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { if (neighbor->visible) { if (!qh ONLYgood) { if (neighbor->visitid == qh visit_id) { - qh_setfree (&(ridge->vertices)); /* delete on 2nd visit */ + qh_setfree(&(ridge->vertices)); /* delete on 2nd visit */ qh_memfree_(ridge, sizeof(ridgeT), freelistp); } } }else { /* neighbor is an horizon facet */ toporient= (ridge->top == visible); - vertices= qh_setnew (qh hull_dim); /* makes sure this is quick */ - qh_setappend (&vertices, apex); - qh_setappend_set (&vertices, ridge->vertices); + 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) { @@ -586,17 +595,17 @@ facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { }else { /* qh_attachnewfacets */ if (neighbor->seen) { if (neighbor->simplicial) { - fprintf (qh ferr, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n", + 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); + qh_setappend(&(neighbor->neighbors), newfacet); }else - qh_setreplace (neighbor->neighbors, visible, newfacet); + qh_setreplace(neighbor->neighbors, visible, newfacet); if (neighbor->simplicial) { - qh_setdel (neighbor->ridges, ridge); - qh_setfree (&(ridge->vertices)); - qh_memfree (ridge, sizeof(ridgeT)); + qh_setdel(neighbor->ridges, ridge); + qh_setfree(&(ridge->vertices)); + qh_memfree(ridge, sizeof(ridgeT)); }else { qh_setappend(&(newfacet->ridges), ridge); if (toporient) @@ -604,7 +613,7 @@ facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { else ridge->bottom= newfacet; } - trace4((qh ferr, "qh_makenew_nonsimplicial: created facet f%d from v%d and r%d of horizon f%d\n", + 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)); } } @@ -615,7 +624,7 @@ facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { return newfacet; } /* makenew_nonsimplicial */ #else /* qh_NOmerge */ -facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { +facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew) { return NULL; } #endif /* qh_NOmerge */ @@ -631,7 +640,7 @@ facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { neighbors between newfacet and horizon notes: - nop if neighbor->seen or neighbor->visible (see qh_makenew_nonsimplicial) + nop if neighbor->seen or neighbor->visible(see qh_makenew_nonsimplicial) design: locate neighboring horizon facet for visible facet @@ -641,7 +650,7 @@ facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) { add new facet to f.samecycle update horizon facet's neighbor list */ -facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew) { +facetT *qh_makenew_simplicial(facetT *visible, vertexT *apex, int *numnew) { facetT *neighbor, **neighborp, *newfacet= NULL; setT *vertices; boolT flip, toporient; @@ -666,7 +675,7 @@ facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew) { } if (!qh ONLYgood) SETelem_(neighbor->neighbors, horizonskip)= newfacet; - trace4((qh ferr, "qh_makenew_simplicial: create facet f%d top %d from v%d and horizon f%d skip %d top %d and visible f%d skip %d, flip? %d\n", + 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)); } @@ -705,16 +714,16 @@ facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew) { 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) { +void qh_matchneighbor(facetT *newfacet, int newskip, int hashsize, int *hashcount) { boolT newfound= False; /* True, if new facet is already in hash chain */ boolT same, ismatch; int hash, scan; facetT *facet, *matchfacet; int skip, matchskip; - hash= (int)qh_gethash (hashsize, newfacet->vertices, qh hull_dim, 1, + hash= (int)qh_gethash(hashsize, newfacet->vertices, qh hull_dim, 1, SETelem_(newfacet->vertices, newskip)); - trace4((qh ferr, "qh_matchneighbor: newfacet f%d skip %d hash %d hashcount %d\n", + 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)); @@ -724,11 +733,11 @@ void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcou continue; } zinc_(Zhashtests); - if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) { + if (qh_matchvertices(1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) { if (SETelem_(newfacet->vertices, newskip) == SETelem_(facet->vertices, skip)) { - qh_precision ("two facets with the same vertices"); - fprintf (qh ferr, "qhull precision error: Vertex sets are the same for f%d and f%d. Can not force output.\n", + 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); } @@ -738,40 +747,40 @@ void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcou SETelem_(facet->neighbors, skip)= newfacet; SETelem_(newfacet->neighbors, newskip)= facet; (*hashcount)--; - trace4((qh ferr, "qh_matchneighbor: f%d skip %d matched with new f%d skip %d\n", + 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"); - fprintf (qh ferr, "qhull precision error: facets f%d, f%d and f%d meet at a ridge with more than 2 neighbors. Can not continue.\n", + 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); + qh_setfacetplane(newfacet); + qh_addhash(newfacet, qh hash_table, hashsize, hash); (*hashcount)++; if (!facet->normal) - qh_setfacetplane (facet); + qh_setfacetplane(facet); if (matchfacet != qh_DUPLICATEridge) { SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge; facet->dupridge= True; if (!facet->normal) - qh_setfacetplane (facet); + qh_setfacetplane(facet); if (matchfacet) { - matchskip= qh_setindex (matchfacet->neighbors, facet); + 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); + qh_setfacetplane(matchfacet); + qh_addhash(matchfacet, qh hash_table, hashsize, hash); *hashcount += 2; } } - trace4((qh ferr, "qh_matchneighbor: new f%d skip %d duplicates ridge for f%d skip %d matching f%d ismatch %d at hash %d\n", + 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)); @@ -781,7 +790,7 @@ void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcou if (!newfound) SETelem_(qh hash_table, scan)= newfacet; /* same as qh_addhash */ (*hashcount)++; - trace4((qh ferr, "qh_matchneighbor: no match for f%d skip %d at hash %d\n", + trace4((qh ferr, 4053, "qh_matchneighbor: no match for f%d skip %d at hash %d\n", newfacet->id, newskip, hash)); } /* matchneighbor */ @@ -817,7 +826,7 @@ void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcou match it with a facet check for flipped facets */ -void qh_matchnewfacets (void /* qh newfacet_list */) { +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; @@ -827,21 +836,21 @@ void qh_matchnewfacets (void /* qh newfacet_list */) { facetT *facet; #endif - trace1((qh ferr, "qh_matchnewfacets: match neighbors for new facets.\n")); + trace1((qh ferr, 1019, "qh_matchnewfacets: match neighbors for new facets.\n")); FORALLnew_facets { numnew++; - { /* inline qh_setzero (newfacet->neighbors, 1, qh hull_dim); */ + { /* 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); + memset((char *)SETelemaddr_(neighbors, 1, void), 0, dim * SETelemsize); } } - qh_newhashtable (numnew*(qh hull_dim-1)); /* twice what is normally needed, + qh_newhashtable(numnew*(qh hull_dim-1)); /* twice what is normally needed, but every ridge could be DUPLICATEridge */ - hashsize= qh_setsize (qh hash_table); + 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); + qh_matchneighbor(newfacet, newskip, hashsize, &hashcount); #if 0 /* use the following to trap hashcount errors */ { int count= 0, k; @@ -858,9 +867,9 @@ void qh_matchnewfacets (void /* qh newfacet_list */) { break; } if (count != hashcount) { - fprintf (qh ferr, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n", + 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); + qh_errexit(qh_ERRqhull, newfacet, NULL); } } #endif /* end of trap code */ @@ -870,7 +879,7 @@ void qh_matchnewfacets (void /* qh newfacet_list */) { if (newfacet->dupridge) { FOREACHneighbor_i_(newfacet) { if (neighbor == qh_DUPLICATEridge) { - qh_matchduplicates (newfacet, neighbor_i, hashsize, &hashcount); + qh_matchduplicates(newfacet, neighbor_i, hashsize, &hashcount); /* this may report MERGEfacet */ } } @@ -878,10 +887,10 @@ void qh_matchnewfacets (void /* qh newfacet_list */) { } } if (hashcount) { - fprintf (qh ferr, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n", + 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); + qh_printhashtable(qh ferr); + qh_errexit(qh_ERRqhull, NULL, NULL); } #ifndef qh_NOtrace if (qh IStracing >= 2) { @@ -889,20 +898,20 @@ void qh_matchnewfacets (void /* qh newfacet_list */) { if (!facet) numfree++; } - fprintf (qh ferr, "qh_matchnewfacets: %d new facets, %d unused hash entries . hashsize %d\n", - numnew, numfree, qh_setsize (qh hash_table)); + 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); + qh_setfree(&qh hash_table); if (qh PREmerge || qh MERGEexact) { if (qh IStracing >= 4) - qh_printfacetlist (qh newfacet_list, NULL, qh_ALL); + qh_printfacetlist(qh newfacet_list, NULL, qh_ALL); FORALLnew_facets { if (newfacet->normal) - qh_checkflipped (newfacet, NULL, qh_ALL); + qh_checkflipped(newfacet, NULL, qh_ALL); } }else if (qh FORCEoutput) - qh_checkflipped_all (qh newfacet_list); /* prints warnings for flipped */ + qh_checkflipped_all(qh newfacet_list); /* prints warnings for flipped */ } /* matchnewfacets */ @@ -926,7 +935,7 @@ void qh_matchnewfacets (void /* qh newfacet_list */) { scan both sets checking for a match test orientation */ -boolT qh_matchvertices (int firstindex, setT *verticesA, int skipA, +boolT qh_matchvertices(int firstindex, setT *verticesA, int skipA, setT *verticesB, int *skipB, boolT *same) { vertexT **elemAp, **elemBp, **skipBp=NULL, **skipAp; @@ -939,14 +948,15 @@ boolT qh_matchvertices (int firstindex, setT *verticesA, int skipA, return False; skipBp= elemBp; /* one extra like FOREACH */ } - }while(*(++elemAp)); + }while (*(++elemAp)); if (!skipBp) skipBp= ++elemBp; *skipB= SETindex_(verticesB, skipB); - *same= !(((ptr_intT)skipA & 0x1) ^ ((ptr_intT)*skipB & 0x1)); - trace4((qh ferr, "qh_matchvertices: matched by skip %d (v%d) and skip %d (v%d) same? %d\n", + /* WARN64 -- This expression on pointers returns 0 or 1 */ + *same= !(int)((((ptr_intT)skipA & 0x1) ^ ((ptr_intT)*skipB & 0x1))); + 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); + return(True); } /* matchvertices */ /*-<a href="qh-poly.htm#TOC" @@ -964,7 +974,7 @@ facetT *qh_newfacet(void) { void **freelistp; /* used !qh_NOmem */ qh_memalloc_(sizeof(facetT), freelistp, facet, facetT); - memset ((char *)facet, 0, sizeof(facetT)); + memset((char *)facet, 0, sizeof(facetT)); if (qh facet_id == qh tracefacet_id) qh tracefacet= facet; facet->id= qh facet_id++; @@ -981,8 +991,8 @@ facetT *qh_newfacet(void) { facet->simplicial= True; facet->good= True; facet->newfacet= True; - trace4((qh ferr, "qh_newfacet: created facet f%d\n", facet->id)); - return (facet); + trace4((qh ferr, 4055, "qh_newfacet: created facet f%d\n", facet->id)); + return(facet); } /* newfacet */ @@ -997,16 +1007,16 @@ ridgeT *qh_newridge(void) { void **freelistp; /* used !qh_NOmem */ qh_memalloc_(sizeof(ridgeT), freelistp, ridge, ridgeT); - memset ((char *)ridge, 0, sizeof(ridgeT)); + memset((char *)ridge, 0, sizeof(ridgeT)); zinc_(Ztotridges); if (qh ridge_id == 0xFFFFFF) { - fprintf(qh ferr, "\ + 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); } ridge->id= qh ridge_id++; - trace4((qh ferr, "qh_newridge: created ridge r%d\n", ridge->id)); - return (ridge); + trace4((qh ferr, 4056, "qh_newridge: created ridge r%d\n", ridge->id)); + return(ridge); } /* newridge */ @@ -1022,11 +1032,13 @@ may have the same identifier. Otherwise output ok.\n", 0xFFFFFF); id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size; notes: + 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) { - long offset, id; +int qh_pointid(pointT *point) { + ptr_intT offset, id; if (!point) id= -3; @@ -1034,13 +1046,13 @@ int qh_pointid (pointT *point) { id= -2; else if (point >= qh first_point && point < qh first_point + qh num_points * qh hull_dim) { - offset= point - qh first_point; + offset= (ptr_intT)(point - qh first_point); id= offset / qh hull_dim; - }else if ((id= qh_setindex (qh other_points, point)) != -1) + }else if ((id= qh_setindex(qh other_points, point)) != -1) id += qh num_points; else id= -1; - return (int) id; + return(int) id; } /* pointid */ /*-<a href="qh-poly.htm#TOC" @@ -1073,7 +1085,7 @@ void qh_removefacet(facetT *facet) { qh facet_list->previous= NULL; } qh num_facets--; - trace4((qh ferr, "qh_removefacet: remove f%d from facet_list\n", facet->id)); + trace4((qh ferr, 4057, "qh_removefacet: remove f%d from facet_list\n", facet->id)); } /* removefacet */ @@ -1100,7 +1112,7 @@ void qh_removevertex(vertexT *vertex) { qh vertex_list->previous= NULL; } qh num_vertices--; - trace4((qh ferr, "qh_removevertex: remove v%d from vertex_list\n", vertex->id)); + trace4((qh ferr, 4058, "qh_removevertex: remove v%d from vertex_list\n", vertex->id)); } /* removevertex */ @@ -1127,22 +1139,22 @@ void qh_removevertex(vertexT *vertex) { removes visible facets from neighbor lists marks unused vertices for deletion */ -void qh_updatevertices (void /*qh newvertex_list, newfacet_list, visible_list*/) { +void qh_updatevertices(void /*qh newvertex_list, newfacet_list, visible_list*/) { facetT *newfacet= NULL, *neighbor, **neighborp, *visible; vertexT *vertex, **vertexp; - trace3((qh ferr, "qh_updatevertices: delete interior vertices and update vertex->neighbors\n")); + 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); + qh_setcompact(vertex->neighbors); } FORALLnew_facets { FOREACHvertex_(newfacet->vertices) - qh_setappend (&vertex->neighbors, newfacet); + qh_setappend(&vertex->neighbors, newfacet); } FORALLvisible_facets { FOREACHvertex_(visible->vertices) { @@ -1152,11 +1164,11 @@ void qh_updatevertices (void /*qh newvertex_list, newfacet_list, visible_list*/) break; } if (neighbor) - qh_setdel (vertex->neighbors, visible); + qh_setdel(vertex->neighbors, visible); else { vertex->deleted= True; - qh_setappend (&qh del_vertices, vertex); - trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n", + qh_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)); } } @@ -1167,8 +1179,8 @@ void qh_updatevertices (void /*qh newvertex_list, newfacet_list, visible_list*/) FOREACHvertex_(visible->vertices) { if (!vertex->newlist && !vertex->deleted) { vertex->deleted= True; - qh_setappend (&qh del_vertices, vertex); - trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n", + qh_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)); } } diff --git a/src/poly.h b/src/poly.h index 2d49c28..1ab18e6 100644 --- a/src/poly.h +++ b/src/poly.h @@ -4,14 +4,18 @@ poly.h header file for poly.c and poly2.c - see qh-poly.htm, qhull.h and poly.c + see qh-poly.htm, qhulllib.h and poly.c - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/poly.h#18 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ #ifndef qhDEFpoly #define qhDEFpoly 1 +#include "qhulllib.h" + /*=============== constants ========================== */ /*-<a href="qh-geom.htm#TOC" @@ -39,7 +43,7 @@ notes: set by matchneighbor, used by matchmatch and mark_dupridge */ -#define qh_DUPLICATEridge ( facetT * ) 1L +#define qh_DUPLICATEridge (facetT *)1L /*-<a href="qh-poly.htm#TOC" >--------------------------------</a><a name="MERGEridge">-</a> @@ -50,7 +54,7 @@ notes: set by matchneighbor, used by matchmatch and mark_dupridge */ -#define qh_MERGEridge ( facetT * ) 2L +#define qh_MERGEridge (facetT *)2L /*============ -structures- ====================*/ @@ -70,7 +74,7 @@ see: FORALLfacets */ -#define FORALLfacet_( facetlist ) if ( facetlist ) for( facet=( facetlist );facet && facet->next;facet=facet->next ) +#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> @@ -82,7 +86,7 @@ uses 'facetT *newfacet;' at exit, newfacet==NULL */ -#define FORALLnew_facets for( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next ) +#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> @@ -94,7 +98,7 @@ uses 'vertexT *vertex;' at exit, vertex==NULL */ -#define FORALLvertex_( vertexlist ) for ( vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next ) +#define FORALLvertex_( vertexlist ) for (vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next ) /*-<a href="qh-poly.htm#TOC" >--------------------------------</a><a name="FORALLvisible_facets">-</a> @@ -205,86 +209,86 @@ void qh_appendfacet(facetT *facet); void qh_appendvertex(vertexT *vertex); -void qh_attachnewfacets (void); -boolT qh_checkflipped (facetT *facet, realT *dist, boolT allerror); +void qh_attachnewfacets(void); +boolT qh_checkflipped(facetT *facet, realT *dist, boolT allerror); void qh_delfacet(facetT *facet); void qh_deletevisible(void /*qh visible_list, qh horizon_list*/); -setT *qh_facetintersect (facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra); -unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem); +setT *qh_facetintersect(facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra); +unsigned qh_gethash(int hashsize, setT *set, int size, int firstindex, void *skipelem); facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet); -void qh_makenewplanes ( void /* newfacet_list */); -facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew); -facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew); -void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, +void qh_makenewplanes(void /* newfacet_list */); +facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew); +facetT *qh_makenew_simplicial(facetT *visible, vertexT *apex, int *numnew); +void qh_matchneighbor(facetT *newfacet, int newskip, int hashsize, int *hashcount); -void qh_matchnewfacets (void); -boolT qh_matchvertices (int firstindex, setT *verticesA, int skipA, +void qh_matchnewfacets(void); +boolT qh_matchvertices(int firstindex, setT *verticesA, int skipA, setT *verticesB, int *skipB, boolT *same); facetT *qh_newfacet(void); ridgeT *qh_newridge(void); -int qh_pointid (pointT *point); +int qh_pointid(pointT *point); void qh_removefacet(facetT *facet); void qh_removevertex(vertexT *vertex); -void qh_updatevertices (void); +void qh_updatevertices(void); /*========== -prototypes poly2.c in alphabetical order ===========*/ -void qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash); -void qh_check_bestdist (void); -void qh_check_maxout (void); -void qh_check_output (void); -void qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2); +void qh_addhash(void* newelem, setT *hashtable, int hashsize, unsigned hash); +void qh_check_bestdist(void); +void qh_check_maxout(void); +void qh_check_output(void); +void qh_check_point(pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2); void qh_check_points(void); void qh_checkconvex(facetT *facetlist, int fault); void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp); -void qh_checkflipped_all (facetT *facetlist); +void qh_checkflipped_all(facetT *facetlist); void qh_checkpolygon(facetT *facetlist); -void qh_checkvertex (vertexT *vertex); -void qh_clearcenters (qh_CENTER type); +void qh_checkvertex(vertexT *vertex); +void qh_clearcenters(qh_CENTER type); void qh_createsimplex(setT *vertices); void qh_delridge(ridgeT *ridge); -void qh_delvertex (vertexT *vertex); -setT *qh_facet3vertex (facetT *facet); -facetT *qh_findbestfacet (pointT *point, boolT bestoutside, +void qh_delvertex(vertexT *vertex); +setT *qh_facet3vertex(facetT *facet); +facetT *qh_findbestfacet(pointT *point, boolT bestoutside, realT *bestdist, boolT *isoutside); -facetT *qh_findbestlower (facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart); -facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside, +facetT *qh_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart); +facetT *qh_findfacet_all(pointT *point, realT *bestdist, boolT *isoutside, int *numpart); -int qh_findgood (facetT *facetlist, int goodhorizon); -void qh_findgood_all (facetT *facetlist); -void qh_furthestnext (void /* qh facet_list */); -void qh_furthestout (facetT *facet); -void qh_infiniteloop (facetT *facet); +int qh_findgood(facetT *facetlist, int goodhorizon); +void qh_findgood_all(facetT *facetlist); +void qh_furthestnext(void /* qh facet_list */); +void qh_furthestout(facetT *facet); +void qh_infiniteloop(facetT *facet); void qh_initbuild(void); void qh_initialhull(setT *vertices); setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints); -vertexT *qh_isvertex (pointT *point, setT *vertices); -vertexT *qh_makenewfacets (pointT *point /*horizon_list, visible_list*/); -void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount); -void qh_nearcoplanar ( void /* qh.facet_list */); -vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp); +vertexT *qh_isvertex(pointT *point, setT *vertices); +vertexT *qh_makenewfacets(pointT *point /*horizon_list, visible_list*/); +void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount); +void qh_nearcoplanar(void /* qh.facet_list */); +vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp); int qh_newhashtable(int newsize); vertexT *qh_newvertex(pointT *point); -ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp); -void qh_outcoplanar (void /* facet_list */); -pointT *qh_point (int id); -void qh_point_add (setT *set, pointT *point, void *elem); -setT *qh_pointfacet (void /*qh facet_list*/); -setT *qh_pointvertex (void /*qh facet_list*/); +ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp); +void qh_outcoplanar(void /* facet_list */); +pointT *qh_point(int id); +void qh_point_add(setT *set, pointT *point, void *elem); +setT *qh_pointfacet(void /*qh facet_list*/); +setT *qh_pointvertex(void /*qh facet_list*/); void qh_prependfacet(facetT *facet, facetT **facetlist); void qh_printhashtable(FILE *fp); -void qh_printlists (void); -void qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/); -void qh_setvoronoi_all (void); -void qh_triangulate (void /*qh facet_list*/); -void qh_triangulate_facet (facetT *facetA, vertexT **first_vertex); -void qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB); -void qh_triangulate_mirror (facetT *facetA, facetT *facetB); -void qh_triangulate_null (facetT *facetA); +void qh_printlists(void); +void qh_resetlists(boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/); +void qh_setvoronoi_all(void); +void qh_triangulate(void /*qh facet_list*/); +void qh_triangulate_facet(facetT *facetA, vertexT **first_vertex); +void qh_triangulate_link(facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB); +void qh_triangulate_mirror(facetT *facetA, facetT *facetB); +void qh_triangulate_null(facetT *facetA); void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB); setT *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB); -void qh_vertexneighbors (void /*qh facet_list*/); +void qh_vertexneighbors(void /*qh facet_list*/); boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB); diff --git a/src/poly2.c b/src/poly2.c index 79ce4af..42ec7c4 100644 --- a/src/poly2.c +++ b/src/poly2.c @@ -4,11 +4,13 @@ poly2.c implements polygons and simplices - see qh-poly.htm, poly.h and qhull.h + see qh-poly.htm, poly.h and qhulllib.h frequently used code is in poly.c - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/poly2.c#32 $$Change: 1095 $ + $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ */ #include "qhull_a.h" @@ -21,7 +23,7 @@ qh_addhash( newelem, hashtable, hashsize, hash ) add newelem to linear hash table at hash if not already there */ -void qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash) { +void qh_addhash(void* newelem, setT *hashtable, int hashsize, unsigned hash) { int scan; void *elem; @@ -61,7 +63,7 @@ void qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash) { find the best facet for the point and check all coplanar facets error if point is outside of facet */ -void qh_check_bestdist (void) { +void qh_check_bestdist(void) { boolT waserror= False, unassigned; facetT *facet, *bestfacet, *errfacet1= NULL, *errfacet2= NULL; facetT *facetlist; @@ -70,15 +72,15 @@ void qh_check_bestdist (void) { int numpart= 0, facet_i, facet_n, notgood= 0, notverified= 0; setT *facets; - trace1((qh ferr, "qh_check_bestdist: check points below nearest facet. Facet_list f%d\n", + 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, "qh_check_bestdist: check that all points are within %2.2g of best facet\n", maxoutside)); - facets= qh_pointfacet (/*qh facet_list*/); + 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) - fprintf (qh ferr, "\n\ + 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 " : "")); @@ -94,17 +96,17 @@ below %2.2g of the nearest %sfacet.\n", continue; qh_distplane(point, facet, &dist); numpart++; - bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, facet, qh_NOupper, &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)) + && !((bestfacet= qh_findgooddist(point, bestfacet, &dist, &facetlist)) && dist > maxoutside)) notgood++; else { waserror= True; - fprintf(qh ferr, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n", + 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; @@ -114,20 +116,19 @@ below %2.2g of the nearest %sfacet.\n", }else if (unassigned && dist < -qh MAXcoplanar) notverified++; } - qh_settempfree (&facets); + qh_settempfree(&facets); if (notverified && !qh DELAUNAY && !qh_QUICKhelp && qh PRINTprecision) - fprintf(qh ferr, "\n%d points were well inside the hull. If the hull contains\n\ + 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) { - fprintf( qh ferr, "qhull precision error (qh_check_bestdist): a coplanar point is %6.2g from convex hull. The maximum value (qh.outside_err) is %6.2g\n", + 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, "qh_check_bestdist: max distance outside %2.2g\n", maxdist)); + /* 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" @@ -163,7 +164,7 @@ options 'Qci Tv' to verify all points.\n", notverified); remove near-inside points from coplanar sets */ #ifndef qh_NOmerge -void qh_check_maxout (void) { +void qh_check_maxout(void) { facetT *facet, *bestfacet, *neighbor, **neighborp, *facetlist; realT dist, maxoutside, minvertex, old_maxoutside; pointT *point; @@ -171,32 +172,32 @@ void qh_check_maxout (void) { setT *facets, *vertices; vertexT *vertex; - trace1((qh ferr, "qh_check_maxout: check and update maxoutside for each facet.\n")); + 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, "qh_check_maxout: determine actual maxoutside and minvertex\n")); - vertices= qh_pointvertex (/*qh facet_list*/); + 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); + qh_distplane(vertex->point, neighbor, &dist); minimize_(minvertex, dist); if (-dist > qh TRACEdist || dist > qh TRACEdist || neighbor == qh tracefacet || vertex == qh tracevertex) - fprintf (qh ferr, "qh_check_maxout: p%d (v%d) is %.2g from f%d\n", - qh_pointid (vertex->point), vertex->id, dist, neighbor->id); + 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); + qh_settempfree(&vertices); } - facets= qh_pointfacet (/*qh facet_list*/); + facets= qh_pointfacet(/*qh facet_list*/); do { old_maxoutside= fmax_(qh max_outside, maxoutside); FOREACHfacet_i_(facets) { /* for each point with facet assignment */ @@ -204,21 +205,21 @@ void qh_check_maxout (void) { point= qh_point(facet_i); if (point == qh GOODpointp) continue; - zinc_(Ztotcheck); + zzinc_(Ztotcheck); qh_distplane(point, facet, &dist); numpart++; - bestfacet= qh_findbesthorizon (qh_IScheckmax, point, facet, !qh_NOupper, &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)) + && !((bestfacet= qh_findgooddist(point, bestfacet, &dist, &facetlist)) && dist > maxoutside)) notgood++; else maxoutside= dist; } if (dist > qh TRACEdist || (bestfacet && bestfacet == qh tracefacet)) - fprintf (qh ferr, "qh_check_maxout: p%d is %.2g above f%d\n", - qh_pointid (point), dist, bestfacet->id); + qh_fprintf(qh ferr, 8094, "qh_check_maxout: p%d is %.2g above f%d\n", + qh_pointid(point), dist, bestfacet->id); } } }while @@ -226,17 +227,17 @@ void qh_check_maxout (void) { /* 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); + qh_settempfree(&facets); wval_(Wmaxout)= maxoutside - qh max_outside; wmax_(Wmaxoutside, qh max_outside); qh max_outside= maxoutside; - qh_nearcoplanar (/*qh.facet_list*/); + qh_nearcoplanar(/*qh.facet_list*/); qh maxoutdone= True; - trace1((qh ferr, "qh_check_maxout: maxoutside %2.2g, min_vertex %2.2g, outside of not good %d\n", + 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) { +void qh_check_maxout(void) { } #endif @@ -247,18 +248,18 @@ void qh_check_maxout (void) { 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) { +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); + 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 */ @@ -270,7 +271,7 @@ void qh_check_output (void) { 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) { +void qh_check_point(pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2) { realT dist; /* occurs after statistics reported */ @@ -280,7 +281,7 @@ void qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *max *errfacet2= *errfacet1; *errfacet1= facet; } - fprintf(qh ferr, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n", + qh_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); @@ -310,7 +311,7 @@ void qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *max for all points check that point is inside facet */ -void qh_check_points (void) { +void qh_check_points(void) { facetT *facet, *errfacet1= NULL, *errfacet2= NULL; realT total, maxoutside, maxdist= -REALmax; pointT *point, **pointp, *pointtemp; @@ -319,7 +320,7 @@ void qh_check_points (void) { maxoutside= qh_maxouter(); maxoutside += qh DISTround; /* one more qh.DISTround for check computation */ - trace1((qh ferr, "qh_check_points: check all points below %2.2g of all facet planes\n", + 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 * qh num_points; @@ -327,8 +328,8 @@ void qh_check_points (void) { total= (float) qh num_facets * qh num_points; if (total >= qh_VERIFYdirect && !qh maxoutdone) { if (!qh_QUICKhelp && qh SKIPcheckmax && qh MERGING) - fprintf (qh ferr, "\n\ -qhull input warning: merging without checking outer planes ('Q5' or 'Po').\n\ + qh_fprintf(qh ferr, 7075, "\n\ +qhull input warning: merging without checking outer planes('Q5' or 'Po').\n\ Verify may report that a point is outside of a facet.\n"); qh_check_bestdist(); }else { @@ -338,23 +339,23 @@ Verify may report that a point is outside of a facet.\n"); testouter= False; if (!qh_QUICKhelp) { if (qh MERGEexact) - fprintf (qh ferr, "\n\ + qh_fprintf(qh ferr, 7076, "\n\ qhull input warning: exact merge ('Qx'). Verify may report that a point\n\ is outside of a facet. See qh-optq.htm#Qx\n"); else if (qh SKIPcheckmax || qh NOnearinside) - fprintf (qh ferr, "\n\ + qh_fprintf(qh ferr, 7077, "\n\ qhull input warning: no outer plane check ('Q5') or no processing of\n\ near-inside points ('Q8'). Verify may report that a point is outside\n\ of a facet.\n"); } if (qh PRINTprecision) { if (testouter) - fprintf (qh ferr, "\n\ + 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 - fprintf (qh ferr, "\n\ + 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); @@ -365,7 +366,7 @@ all %sfacets. Will make %2.0f distance computations.\n", if (facet->flipped) continue; if (!facet->normal) { - fprintf( qh ferr, "qhull warning (qh_check_points): missing normal for facet f%d\n", facet->id); + qh_fprintf(qh ferr, 7061, "qhull warning (qh_check_points): missing normal for facet f%d\n", facet->id); continue; } if (testouter) { @@ -376,22 +377,21 @@ all %sfacets. Will make %2.0f distance computations.\n", } FORALLpoints { if (point != qh GOODpointp) - qh_check_point (point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2); + 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); + qh_check_point(point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2); } } if (maxdist > qh outside_err) { - fprintf( qh ferr, "qhull precision error (qh_check_points): a coplanar point is %6.2g from convex hull. The maximum value (qh.outside_err) is %6.2g\n", + 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, "qh_check_points: max distance outside %2.2g\n", maxdist)); + /* 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 */ @@ -432,15 +432,15 @@ void qh_checkconvex(facetT *facetlist, int fault) { boolT waserror= False, centrum_warning= False, tempcentrum= False, allsimplicial; int neighbor_i; - trace1((qh ferr, "qh_checkconvex: check all ridges are convex\n")); + 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"); - fprintf (qh ferr, "qhull precision error: f%d is flipped (interior point is outside)\n", + 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; @@ -457,17 +457,17 @@ void qh_checkconvex(facetT *facetlist, int fault) { allsimplicial= False; continue; } - qh_distplane (vertex->point, neighbor, &dist); + qh_distplane(vertex->point, neighbor, &dist); if (dist > -qh DISTround) { if (fault == qh_DATAfault) { - qh_precision ("coplanar or concave ridge"); - fprintf (qh ferr, "qhull precision error: initial simplex is not convex. Distance=%.2g\n", dist); + qh_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"); - fprintf (qh ferr, "qhull precision error: f%d is concave to f%d, since p%d (v%d) is %6.4g above\n", + 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; @@ -475,8 +475,8 @@ void qh_checkconvex(facetT *facetlist, int fault) { }else if (qh ZEROcentrum) { if (dist > 0) { /* qh_checkzero checks that dist < - qh DISTround */ zzinc_(Zcoplanarridges); - qh_precision ("coplanar ridge"); - fprintf (qh ferr, "qhull precision error: f%d is clearly not convex to f%d, since p%d (v%d) is %6.4g above\n", + 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; @@ -484,8 +484,8 @@ void qh_checkconvex(facetT *facetlist, int fault) { } }else { zzinc_(Zcoplanarridges); - qh_precision ("coplanar ridge"); - trace0((qh ferr, "qhull precision error: f%d may be coplanar to f%d, since p%d (v%d) is within %6.4g during p%d\n", + 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)); } } @@ -494,12 +494,12 @@ void qh_checkconvex(facetT *facetlist, int fault) { if (!allsimplicial) { if (qh CENTERtype == qh_AScentrum) { if (!facet->center) - facet->center= qh_getcentrum (facet); + facet->center= qh_getcentrum(facet); centrum= facet->center; }else { if (!centrum_warning && (!facet->simplicial || facet->tricoplanar)) { centrum_warning= True; - fprintf (qh ferr, "qhull note: recomputing centrums for convexity test. This may lead to false, precision errors.\n"); + 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; @@ -510,11 +510,11 @@ void qh_checkconvex(facetT *facetlist, int fault) { if (facet->tricoplanar || neighbor->tricoplanar) continue; zzinc_(Zdistconvex); - qh_distplane (centrum, neighbor, &dist); + qh_distplane(centrum, neighbor, &dist); if (dist > qh DISTround) { zzinc_(Zconcaveridges); - qh_precision ("concave ridge"); - fprintf (qh ferr, "qhull precision error: f%d is concave to f%d. Centrum of f%d is %6.4g above f%d\n", + 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; @@ -522,8 +522,8 @@ void qh_checkconvex(facetT *facetlist, int fault) { }else if (dist >= 0.0) { /* if arithmetic always rounds the same, can test against centrum radius instead */ zzinc_(Zcoplanarridges); - qh_precision ("coplanar ridge"); - fprintf (qh ferr, "qhull precision error: f%d is coplanar or concave to f%d. Centrum of f%d is %6.4g above f%d\n", + 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; @@ -587,28 +587,28 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { setT *intersection; if (facet->visible) { - fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d is on the visible_list\n", + 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); + qh_errexit(qh_ERRqhull, facet, NULL); } if (!facet->normal) { - fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d does not have a normal\n", + 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); + qh_setcheck(facet->vertices, "vertices for f", facet->id); + qh_setcheck(facet->ridges, "ridges for f", facet->id); + qh_setcheck(facet->outsideset, "outsideset for f", facet->id); + qh_setcheck(facet->coplanarset, "coplanarset for f", facet->id); + qh_setcheck(facet->neighbors, "neighbors for f", facet->id); FOREACHvertex_(facet->vertices) { if (vertex->deleted) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): deleted vertex v%d in f%d\n", vertex->id, facet->id); - qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex); + 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) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): vertices of f%d are not in descending id order at v%d\n", facet->id, vertex->id); + 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; } @@ -620,16 +620,16 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { if (facet->simplicial) { if (numvertices+numneighbors != 2*qh hull_dim && !facet->degenerate && !facet->redundant) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): for simplicial facet f%d, #vertices %d + #neighbors %d != 2*qh hull_dim\n", + 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); + qh_setprint(qh ferr, "", facet->neighbors); waserror= True; } }else { /* non-simplicial */ if (!newmerge &&(numvertices < qh hull_dim || numneighbors < qh hull_dim) && !facet->degenerate && !facet->redundant) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, #vertices %d or #neighbors %d < qh hull_dim\n", + 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; } @@ -638,7 +638,7 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { ||(qh hull_dim == 3 && numvertices > numridges && !qh NEWfacets) ||(qh hull_dim == 2 && numridges + numvertices + numneighbors != 6)) { if (!facet->degenerate && !facet->redundant) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, #ridges %d < #neighbors %d or (3-d) > #vertices %d or (2-d) not all 2\n", + 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; } @@ -646,20 +646,20 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { } FOREACHneighbor_(facet) { if (neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d still has a MERGE or DUP neighbor\n", facet->id); - qh_errexit (qh_ERRqhull, facet, NULL); + 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)) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has neighbor f%d, but f%d does not have neighbor f%d\n", + 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) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has a duplicate neighbor f%d\n", + 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; @@ -667,12 +667,12 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { neighbor->seen= False; } FOREACHridge_(facet->ridges) { - qh_setcheck (ridge->vertices, "vertices for r", ridge->id); + qh_setcheck(ridge->vertices, "vertices for r", ridge->id); ridge->seen= False; } FOREACHridge_(facet->ridges) { if (ridge->seen) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has a duplicate ridge r%d\n", + 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; @@ -680,7 +680,7 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { ridge->seen= True; numRvertices= qh_setsize(ridge->vertices); if (numRvertices != qh hull_dim - 1) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): ridge between f%d and f%d has %d vertices\n", + 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; @@ -688,7 +688,7 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { neighbor= otherfacet_(ridge, facet); neighbor->seen= True; if (!qh_setin(facet->neighbors, neighbor)) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, neighbor f%d of ridge r%d not in facet\n", + 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; @@ -697,13 +697,13 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { if (!facet->simplicial) { FOREACHneighbor_(facet) { if (!neighbor->seen) { - fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d does not have a ridge for neighbor f%d\n", + 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); + qh_settemppush(intersection); FOREACHvertex_(facet->vertices) { vertex->seen= False; vertex->seen2= False; @@ -715,9 +715,9 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { continue; FOREACHvertex_(ridge->vertices) { if (!vertex->seen) { - fprintf (qh ferr, "qhull internal error (qh_checkfacet): vertex v%d in r%d not in f%d intersect f%d\n", + 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); + qh_errexit(qh_ERRqhull, facet, ridge); } vertex->seen2= True; } @@ -726,27 +726,27 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { FOREACHvertex_(intersection) { if (!vertex->seen2) { if (qh IStracing >=3 || !qh MERGING) { - fprintf (qh ferr, "qhull precision error (qh_checkfacet): vertex v%d in f%d intersect f%d but\n\ + 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); + qh_errprint("ERRONEOUS", facet, neighbor, NULL, vertex); if (!qh MERGING) - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); } } } } } - qh_settempfree (&intersection); + qh_settempfree(&intersection); } }else { /* simplicial */ FOREACHneighbor_(facet) { if (neighbor->simplicial) { skipA= SETindex_(facet->neighbors, neighbor); - skipB= qh_setindex (neighbor->neighbors, facet); - if (!qh_setequal_skip (facet->vertices, skipA, neighbor->vertices, skipB)) { - fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d skip %d and neighbor f%d skip %d do not match \n", + 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; @@ -756,10 +756,10 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { } if (qh hull_dim < 5 && (qh IStracing > 2 || qh CHECKfrequently)) { FOREACHridge_i_(facet->ridges) { /* expensive */ - for (i= ridge_i+1; i < ridge_n; i++) { + for (i=ridge_i+1; i < ridge_n; i++) { ridge2= SETelemt_(facet->ridges, i, ridgeT); - if (qh_setequal (ridge->vertices, ridge2->vertices)) { - fprintf (qh ferr, "qh_checkfacet: ridges r%d and r%d have the same vertices\n", + 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; @@ -780,7 +780,7 @@ void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) { qh_checkflipped_all( facetlist ) checks orientation of facets in list against interior point */ -void qh_checkflipped_all (facetT *facetlist) { +void qh_checkflipped_all(facetT *facetlist) { facetT *facet; boolT waserror= False; realT dist; @@ -788,8 +788,8 @@ void qh_checkflipped_all (facetT *facetlist) { if (facetlist == qh facet_list) zzval_(Zflippedfacets)= 0; FORALLfacet_(facetlist) { - if (facet->normal && !qh_checkflipped (facet, &dist, !qh_ALL)) { - fprintf(qh ferr, "qhull precision error: facet f%d is flipped, distance= %6.12g\n", + 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); @@ -798,7 +798,7 @@ void qh_checkflipped_all (facetT *facetlist) { } } if (waserror) { - fprintf (qh ferr, "\n\ + 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); @@ -821,7 +821,7 @@ greater than %2.2g, the maximum roundoff error.\n", -qh DISTround); initializes vertexlist for each facet checks vertex set - if checking all facets (qh.facetlist) + if checking all facets(qh.facetlist) check facet count if qh.VERTEXneighbors check vertex neighbors and count @@ -834,7 +834,7 @@ void qh_checkpolygon(facetT *facetlist) { int totvneighbors= 0, totvertices= 0; boolT waserror= False, nextseen= False, visibleseen= False; - trace1((qh ferr, "qh_checkpolygon: check all facets from f%d\n", facetlist->id)); + 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) { @@ -844,15 +844,15 @@ void qh_checkpolygon(facetT *facetlist) { if (!nextseen) { if (facet == qh facet_next) nextseen= True; - else if (qh_setsize (facet->outsideset)) { + else if (qh_setsize(facet->outsideset)) { if (!qh NARROWhull #if !qh_COMPUTEfurthest || facet->furthestdist >= qh MINoutside #endif ) { - fprintf (qh ferr, "qhull internal error (qh_checkpolygon): f%d has outside points before qh facet_next\n", + 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); + qh_errexit(qh_ERRqhull, facet, NULL); } } } @@ -861,9 +861,9 @@ void qh_checkpolygon(facetT *facetlist) { } } if (qh visible_list && !visibleseen && facetlist == qh facet_list) { - fprintf (qh ferr, "qhull internal error (qh_checkpolygon): visible list f%d no longer on facet list\n", qh visible_list->id); + qh_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); + qh_errexit(qh_ERRqhull, qh visible_list, NULL); } if (facetlist == qh facet_list) vertexlist= qh vertex_list; @@ -881,14 +881,14 @@ void qh_checkpolygon(facetT *facetlist) { if (facet->simplicial) numridges += qh hull_dim; else - numridges += qh_setsize (facet->ridges); + numridges += qh_setsize(facet->ridges); FOREACHvertex_(facet->vertices) { vertex->visitid++; if (!vertex->seen) { vertex->seen= True; numvertices++; - if (qh_pointid (vertex->point) == -1) { - fprintf (qh ferr, "qhull internal error (qh_checkpolygon): unknown point %p for vertex v%d first_point %p\n", + if (qh_pointid(vertex->point) == -1) { + 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; } @@ -898,38 +898,38 @@ void qh_checkpolygon(facetT *facetlist) { qh vertex_visit += numfacets; if (facetlist == qh facet_list) { if (numfacets != qh num_facets - qh num_visible) { - fprintf(qh ferr, "qhull internal error (qh_checkpolygon): actual number of facets is %d, cumulative facet count is %d - %d visible facets\n", + 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); + qh_setcheck(vertex->neighbors, "neighbors for v", vertex->id); if (vertex->deleted) continue; - totvneighbors += qh_setsize (vertex->neighbors); + totvneighbors += qh_setsize(vertex->neighbors); } FORALLfacet_(facetlist) - totvertices += qh_setsize (facet->vertices); + totvertices += qh_setsize(facet->vertices); if (totvneighbors != totvertices) { - fprintf(qh ferr, "qhull internal error (qh_checkpolygon): vertex neighbors inconsistent. Totvneighbors %d, totvertices %d\n", + 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)) { - fprintf(qh ferr, "qhull internal error (qh_checkpolygon): actual number of vertices is %d, cumulative vertex count is %d\n", + 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) { - fprintf (qh ferr, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n", + 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) { - fprintf (qh ferr, "qhull warning: #vertices %d + #facets %d - #edges %d != 2\n\ + 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 */ @@ -950,23 +950,23 @@ void qh_checkpolygon(facetT *facetlist) { notes: neighbors checked efficiently in checkpolygon */ -void qh_checkvertex (vertexT *vertex) { +void qh_checkvertex(vertexT *vertex) { boolT waserror= False; facetT *neighbor, **neighborp, *errfacet=NULL; - if (qh_pointid (vertex->point) == -1) { - fprintf (qh ferr, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point); + if (qh_pointid(vertex->point) == -1) { + 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) { - fprintf (qh ferr, "qhull internal error (qh_checkvertex): unknown vertex id %d\n", 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)) { + if (qh_setsize(vertex->neighbors)) { FOREACHneighbor_(vertex) { - if (!qh_setin (neighbor->vertices, vertex)) { - fprintf (qh ferr, "qhull internal error (qh_checkvertex): neighbor f%d does not contain v%d\n", neighbor->id, vertex->id); + 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; } @@ -974,8 +974,8 @@ void qh_checkvertex (vertexT *vertex) { } } if (waserror) { - qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex); - qh_errexit (qh_ERRqhull, errfacet, NULL); + qh_errprint("ERRONEOUS", NULL, NULL, NULL, vertex); + qh_errexit(qh_ERRqhull, errfacet, NULL); } } /* checkvertex */ @@ -989,26 +989,28 @@ void qh_checkvertex (vertexT *vertex) { sets new centertype nop if CENTERtype is the same */ -void qh_clearcenters (qh_CENTER type) { +void qh_clearcenters(qh_CENTER type) { facetT *facet; if (qh CENTERtype != type) { FORALLfacets { - if (qh CENTERtype == qh_ASvoronoi){ + if (facet->tricoplanar && !facet->keepcentrum) + facet->center= NULL; + else if (qh CENTERtype == qh_ASvoronoi){ if (facet->center) { - qh_memfree (facet->center, qh center_size); + 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); + qh_memfree(facet->center, qh normal_size); facet->center= NULL; } } } qh CENTERtype= type; } - trace2((qh ferr, "qh_clearcenters: switched to center type %d\n", type)); + trace2((qh ferr, 2043, "qh_clearcenters: switched to center type %d\n", type)); } /* clearcenters */ /*-<a href="qh-poly.htm#TOC" @@ -1033,7 +1035,7 @@ 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); + setT *newfacets= qh_settemp(qh hull_dim+1); vertexT *vertex; qh facet_list= qh newfacet_list= qh facet_tail= qh_newfacet(); @@ -1041,13 +1043,13 @@ void qh_createsimplex(setT *vertices) { 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, + newfacet->vertices= qh_setnew_delnthsorted(vertices, vertex_n, vertex_i, 0); newfacet->toporient= toporient; qh_appendfacet(newfacet); newfacet->newfacet= True; - qh_appendvertex (vertex); - qh_setappend (&newfacets, newfacet); + qh_appendvertex(vertex); + qh_setappend(&newfacets, newfacet); toporient ^= True; } FORALLnew_facets { @@ -1056,10 +1058,10 @@ void qh_createsimplex(setT *vertices) { if (facet != newfacet) SETelem_(newfacet->neighbors, nth++)= facet; } - qh_settruncate (newfacet->neighbors, qh hull_dim); + qh_settruncate(newfacet->neighbors, qh hull_dim); } - qh_settempfree (&newfacets); - trace1((qh ferr, "qh_createsimplex: created simplex\n")); + qh_settempfree(&newfacets); + trace1((qh ferr, 1028, "qh_createsimplex: created simplex\n")); } /* createsimplex */ /*-<a href="qh-poly.htm#TOC" @@ -1093,12 +1095,12 @@ void qh_delridge(ridgeT *ridge) { assumes vertex->adjacencies have been updated if needed unlinks from vertex_list */ -void qh_delvertex (vertexT *vertex) { +void qh_delvertex(vertexT *vertex) { if (vertex == qh tracevertex) qh tracevertex= NULL; - qh_removevertex (vertex); - qh_setfree (&vertex->neighbors); + qh_removevertex(vertex); + qh_setfree(&vertex->neighbors); qh_memfree(vertex, sizeof(vertexT)); } /* delvertex */ @@ -1116,35 +1118,35 @@ void qh_delvertex (vertexT *vertex) { for each ridge in order build set from ridge's vertices */ -setT *qh_facet3vertex (facetT *facet) { +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); + vertices= qh_settemp(cntvertices); if (facet->simplicial) { if (cntvertices != 3) { - fprintf (qh ferr, "qhull internal error (qh_facet3vertex): only %d vertices for simplicial facet f%d\n", + 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)); + qh_setappend(&vertices, SETfirst_(facet->vertices)); if (facet->toporient ^ qh_ORIENTclock) - qh_setappend (&vertices, SETsecond_(facet->vertices)); + qh_setappend(&vertices, SETsecond_(facet->vertices)); else - qh_setaddnth (&vertices, 0, SETsecond_(facet->vertices)); - qh_setappend (&vertices, SETelem_(facet->vertices, 2)); + 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); + while ((ridge= qh_nextridge3d(ridge, facet, &vertex))) { + qh_setappend(&vertices, vertex); if (++cntprojected > cntvertices || ridge == firstridge) break; } if (!ridge || cntprojected != cntvertices) { - fprintf (qh ferr, "qhull internal error (qh_facet3vertex): ridges for facet %d don't match up. got at least %d\n", + 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); } @@ -1175,7 +1177,7 @@ setT *qh_facet3vertex (facetT *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-in.htm#findfacet">locate a facet with qh_findbestfacet()</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. @@ -1186,26 +1188,26 @@ setT *qh_facet3vertex (facetT *facet) { see: <a href="geom.c#findbest">qh_findbest</a> */ -facetT *qh_findbestfacet (pointT *point, boolT bestoutside, +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, + 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); + bestfacet= qh_findfacet_all(point, bestdist, isoutside, &numpart); totpart += numpart; if ((isoutside && bestoutside) || (!isoutside && bestfacet->upperdelaunay)) { - bestfacet= qh_findbest (point, bestfacet, + bestfacet= qh_findbest(point, bestfacet, bestoutside, False, bestoutside, bestdist, isoutside, &totpart); totpart += numpart; } } - trace3((qh ferr, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n", + trace3((qh ferr, 3014, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n", bestfacet->id, *bestdist, *isoutside, totpart)); return bestfacet; } /* findbestfacet */ @@ -1225,7 +1227,7 @@ facetT *qh_findbestfacet (pointT *point, boolT bestoutside, called by qh_findbest() for points above an upperdelaunay facet */ -facetT *qh_findbestlower (facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart) { +facetT *qh_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart) { facetT *neighbor, **neighborp, *bestfacet= NULL; realT bestdist= -REALmax/2 /* avoid underflow */; realT dist; @@ -1236,7 +1238,7 @@ facetT *qh_findbestlower (facetT *upperfacet, pointT *point, realT *bestdistp, i if (neighbor->upperdelaunay || neighbor->flipped) continue; (*numpart)++; - qh_distplane (point, neighbor, &dist); + qh_distplane(point, neighbor, &dist); if (dist > bestdist) { bestfacet= neighbor; bestdist= dist; @@ -1245,13 +1247,13 @@ facetT *qh_findbestlower (facetT *upperfacet, pointT *point, realT *bestdistp, i if (!bestfacet) { zinc_(Zbestlowerv); /* rarely called, numpart does not count nearvertex computations */ - vertex= qh_nearvertex (upperfacet, point, &dist); + vertex= qh_nearvertex(upperfacet, point, &dist); qh_vertexneighbors(); FOREACHneighbor_(vertex) { if (neighbor->upperdelaunay || neighbor->flipped) continue; (*numpart)++; - qh_distplane (point, neighbor, &dist); + qh_distplane(point, neighbor, &dist); if (dist > bestdist) { bestfacet= neighbor; bestdist= dist; @@ -1259,14 +1261,14 @@ facetT *qh_findbestlower (facetT *upperfacet, pointT *point, realT *bestdistp, i } } if (!bestfacet) { - fprintf(qh ferr, "\n\ -qh_findbestlower: all neighbors of facet %d are flipped or upper Delaunay.\n\ + 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); + qh_errexit(qh_ERRqhull, upperfacet, NULL); } *bestdistp= bestdist; - trace3((qh ferr, "qh_findbestlower: f%d dist %2.2g for f%d p%d\n", + 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 */ @@ -1288,20 +1290,23 @@ Please report this error to qhull_bug@qhull.org with the input and all of the ou 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, +facetT *qh_findfacet_all(pointT *point, realT *bestdist, boolT *isoutside, int *numpart) { facetT *bestfacet= NULL, *facet; realT dist; int totpart= 0; - *bestdist= REALmin; + *bestdist= -REALmax; *isoutside= False; FORALLfacets { if (facet->flipped || !facet->normal) continue; totpart++; - qh_distplane (point, facet, &dist); + qh_distplane(point, facet, &dist); if (dist > *bestdist) { *bestdist= dist; bestfacet= facet; @@ -1312,7 +1317,7 @@ facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside, } } *numpart= totpart; - trace3((qh ferr, "qh_findfacet_all: f%d dist %2.2g isoutside %d totpart %d\n", + 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 */ @@ -1349,7 +1354,7 @@ facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside, if necessary update qh.GOODclosest */ -int qh_findgood (facetT *facetlist, int goodhorizon) { +int qh_findgood(facetT *facetlist, int goodhorizon) { facetT *facet, *bestfacet= NULL; realT angle, bestangle= REALmax, dist; int numgood=0; @@ -1360,7 +1365,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { } if (qh GOODvertex>0 && !qh MERGING) { FORALLfacet_(facetlist) { - if (!qh_isvertex (qh GOODvertexp, facet->vertices)) { + if (!qh_isvertex(qh GOODvertexp, facet->vertices)) { facet->good= False; numgood--; } @@ -1370,7 +1375,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { FORALLfacet_(facetlist) { if (facet->good && facet->normal) { zinc_(Zdistgood); - qh_distplane (qh GOODpointp, facet, &dist); + qh_distplane(qh GOODpointp, facet, &dist); if ((qh GOODpoint > 0) ^ (dist > 0.0)) { facet->good= False; numgood--; @@ -1381,7 +1386,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { if (qh GOODthreshold && (numgood || goodhorizon || qh GOODclosest)) { FORALLfacet_(facetlist) { if (facet->good && facet->normal) { - if (!qh_inthresholds (facet->normal, &angle)) { + if (!qh_inthresholds(facet->normal, &angle)) { facet->good= False; numgood--; if (angle < bestangle) { @@ -1396,7 +1401,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { if (qh GOODclosest->visible) qh GOODclosest= NULL; else { - qh_inthresholds (qh GOODclosest->normal, &angle); + qh_inthresholds(qh GOODclosest->normal, &angle); if (angle < bestangle) bestfacet= qh GOODclosest; } @@ -1407,7 +1412,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { qh GOODclosest= bestfacet; bestfacet->good= True; numgood++; - trace2((qh ferr, "qh_findgood: f%d is closest (%2.2g) to thresholds\n", + trace2((qh ferr, 2044, "qh_findgood: f%d is closest(%2.2g) to thresholds\n", bestfacet->id, bestangle)); return numgood; } @@ -1417,7 +1422,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { } } zadd_(Zgoodfacet, numgood); - trace2((qh ferr, "qh_findgood: found %d good facets with %d good horizon\n", + 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; @@ -1449,7 +1454,7 @@ int qh_findgood (facetT *facetlist, int goodhorizon) { marks facets for qh.GOODvertex marks facets for qh.SPLITthreholds */ -void qh_findgood_all (facetT *facetlist) { +void qh_findgood_all(facetT *facetlist) { facetT *facet, *bestfacet=NULL; realT angle, bestangle= REALmax; int numgood=0, startgood; @@ -1458,24 +1463,24 @@ void qh_findgood_all (facetT *facetlist) { && !qh SPLITthresholds) return; if (!qh ONLYgood) - qh_findgood (qh facet_list, 0); + 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 (facet->good && ((qh GOODvertex > 0) ^ !!qh_isvertex(qh GOODvertexp, facet->vertices))) { if (!--numgood) { if (qh ONLYgood) { - fprintf (qh ferr, "qhull warning: good vertex p%d does not match last good facet f%d. Ignored.\n", + qh_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) - fprintf (qh ferr, "qhull warning: point p%d is not a vertex ('QV%d').\n", + qh_fprintf(qh ferr, 7065, "qhull warning: point p%d is not a vertex('QV%d').\n", qh GOODvertex-1, qh GOODvertex-1); else - fprintf (qh ferr, "qhull warning: point p%d is a vertex for every facet ('QV-%d').\n", + qh_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; @@ -1486,7 +1491,7 @@ void qh_findgood_all (facetT *facetlist) { if (qh SPLITthresholds) { FORALLfacet_(facetlist) { if (facet->good) { - if (!qh_inthresholds (facet->normal, &angle)) { + if (!qh_inthresholds(facet->normal, &angle)) { facet->good= False; numgood--; if (angle < bestangle) { @@ -1499,13 +1504,13 @@ void qh_findgood_all (facetT *facetlist) { if (!numgood && bestfacet) { bestfacet->good= True; numgood++; - trace0((qh ferr, "qh_findgood_all: f%d is closest (%2.2g) to thresholds\n", + 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, "qh_findgood_all: %d good facets remain out of %d facets\n", + trace0((qh ferr, 24, "qh_findgood_all: %d good facets remain out of %d facets\n", numgood, startgood)); } /* findgood_all */ @@ -1519,7 +1524,7 @@ void qh_findgood_all (facetT *facetlist) { notes: this may help avoid precision problems */ -void qh_furthestnext (void /* qh facet_list */) { +void qh_furthestnext(void /* qh facet_list */) { facetT *facet, *bestfacet= NULL; realT dist, bestdist= -REALmax; @@ -1527,9 +1532,9 @@ void qh_furthestnext (void /* qh facet_list */) { if (facet->outsideset) { #if qh_COMPUTEfurthest pointT *furthest; - furthest= (pointT*)qh_setlast (facet->outsideset); + furthest= (pointT*)qh_setlast(facet->outsideset); zinc_(Zcomputefurthest); - qh_distplane (furthest, facet, &dist); + qh_distplane(furthest, facet, &dist); #else dist= facet->furthestdist; #endif @@ -1540,9 +1545,9 @@ void qh_furthestnext (void /* qh facet_list */) { } } if (bestfacet) { - qh_removefacet (bestfacet); - qh_prependfacet (bestfacet, &qh facet_next); - trace1((qh ferr, "qh_furthestnext: made f%d next facet (dist %.2g)\n", + 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 */ @@ -1562,12 +1567,12 @@ void qh_furthestnext (void /* qh facet_list */) { determine best point of outsideset make it the last point of outsideset */ -void qh_furthestout (facetT *facet) { +void qh_furthestout(facetT *facet) { pointT *point, **pointp, *bestpoint= NULL; realT dist, bestdist= -REALmax; FOREACHpoint_(facet->outsideset) { - qh_distplane (point, facet, &dist); + qh_distplane(point, facet, &dist); zinc_(Zcomputefurthest); if (dist > bestdist) { bestpoint= point; @@ -1575,15 +1580,15 @@ void qh_furthestout (facetT *facet) { } } if (bestpoint) { - qh_setdel (facet->outsideset, point); - qh_setappend (&facet->outsideset, point); + qh_setdel(facet->outsideset, point); + qh_setappend(&facet->outsideset, point); #if !qh_COMPUTEfurthest facet->furthestdist= bestdist; #endif } facet->notfurthest= False; - trace3((qh ferr, "qh_furthestout: p%d is furthest outside point of f%d\n", - qh_pointid (point), facet->id)); + trace3((qh ferr, 3017, "qh_furthestout: p%d is furthest outside point of f%d\n", + qh_pointid(point), facet->id)); } /* furthestout */ @@ -1593,10 +1598,10 @@ void qh_furthestout (facetT *facet) { qh_infiniteloop( facet ) report infinite loop error due to facet */ -void qh_infiniteloop (facetT *facet) { +void qh_infiniteloop(facetT *facet) { - fprintf (qh ferr, "qhull internal error (qh_infiniteloop): potential infinite loop detected\n"); - qh_errexit (qh_ERRqhull, facet, NULL); + qh_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" @@ -1616,7 +1621,7 @@ void qh_infiniteloop (facetT *facet) { 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') + if qh.SCALElast, scale last coordinate(for 'd') build initial simplex partition input points into facets of initial simplex set up lists @@ -1638,31 +1643,31 @@ void qh_initbuild( void) { qh maxoutdone= False; if (qh GOODpoint > 0) - qh GOODpointp= qh_point (qh GOODpoint-1); + qh GOODpointp= qh_point(qh GOODpoint-1); else if (qh GOODpoint < 0) - qh GOODpointp= qh_point (-qh GOODpoint-1); + qh GOODpointp= qh_point(-qh GOODpoint-1); if (qh GOODvertex > 0) - qh GOODvertexp= qh_point (qh GOODvertex-1); + qh GOODvertexp= qh_point(qh GOODvertex-1); else if (qh GOODvertex < 0) - qh GOODvertexp= qh_point (-qh GOODvertex-1); + 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 GOODpointp > qh_point(qh num_points-1))) || (qh GOODvertex && (qh GOODvertexp < qh first_point /* also catches !GOODvertexp */ - || qh GOODvertexp > qh_point (qh num_points-1)))) { - fprintf (qh ferr, "qhull input error: either QGn or QVn point is > p%d\n", + || qh 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); + 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_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--; ) { + 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 */ @@ -1680,53 +1685,53 @@ void qh_initbuild( void) { } } 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); + qh_initialhull(vertices); /* initial qh facet_list */ + qh_partitionall(vertices, qh first_point, qh num_points); if (qh PRINToptions1st || qh TRACElevel || qh IStracing) { if (qh TRACElevel || qh IStracing) - fprintf (qh ferr, "\nTrace level %d for %s | %s\n", + qh_fprintf(qh ferr, 8103, "\nTrace level %d for %s | %s\n", qh IStracing ? qh IStracing : qh TRACElevel, qh rbox_command, qh qhull_command); - fprintf (qh ferr, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options); + qh_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_resetlists(False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */); qh facet_next= qh facet_list; - qh_furthestnext (/* qh facet_list */); + qh_furthestnext(/* qh facet_list */); if (qh PREmerge) { qh cos_max= qh premerge_cos; qh centrum_radius= qh premerge_centrum; } if (qh ONLYgood) { if (qh GOODvertex > 0 && qh MERGING) { - fprintf (qh ferr, "qhull input error: 'Qg QVn' (only good vertex) does not work with merging.\nUse 'QJ' to joggle the input or 'Q0' to turn off merging.\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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))) { - fprintf (qh ferr, "qhull input error: 'Qg' (ONLYgood) needs a good threshold ('Pd0D0'), a\n\ -good point (QGn or QG-n), or a good vertex with 'QJ' or 'Q0' (QVn).\n"); - qh_errexit (qh_ERRinput, NULL, NULL); + 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, + && !qh_isvertex(qh GOODvertexp, vertices)) { + facet= qh_findbestnew(qh GOODvertexp, qh facet_list, &dist, !qh_ALL, &isoutside, &numpart); zadd_(Zdistgood, numpart); if (!isoutside) { - fprintf (qh ferr, "qhull input error: point for QV%d is inside initial simplex. It can not be made a vertex.\n", + qh_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); + qh_errexit(qh_ERRinput, NULL, NULL); } - if (!qh_addpoint (qh GOODvertexp, facet, False)) { + if (!qh_addpoint(qh GOODvertexp, facet, False)) { qh_settempfree(&vertices); qh_settempfree(&maxpoints); return; } } - qh_findgood (qh facet_list, 0); + qh_findgood(qh facet_list, 0); } qh_settempfree(&vertices); qh_settempfree(&maxpoints); - trace1((qh ferr, "qh_initbuild: initial hull created and points partitioned\n")); + trace1((qh ferr, 1030, "qh_initbuild: initial hull created and points partitioned\n")); } /* initbuild */ /*-<a href="qh-poly.htm#TOC" @@ -1751,7 +1756,7 @@ void qh_initialhull(setT *vertices) { #endif qh_createsimplex(vertices); /* qh facet_list */ - qh_resetlists (False, qh_RESETvisible); + 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; @@ -1765,25 +1770,25 @@ void qh_initialhull(setT *vertices) { FORALLfacets qh_setfacetplane(facet); FORALLfacets { - if (!qh_checkflipped (facet, NULL, qh_ALL)) {/* due to axis-parallel facet */ - trace1((qh ferr, "qh_initialhull: initial orientation incorrect. Correct all facets\n")); + 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 ^= True; - qh_orientoutside (facet); + qh_orientoutside(facet); } break; } } FORALLfacets { - if (!qh_checkflipped (facet, NULL, !qh_ALL)) { /* can happen with 'R0.1' */ - qh_precision ("initial facet is coplanar with interior point"); - fprintf (qh ferr, "qhull precision error: initial facet %d is coplanar with the interior point\n", + if (!qh_checkflipped(facet, NULL, !qh_ALL)) { /* can happen with 'R0.1' */ + 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); + qh_errexit(qh_ERRsingular, facet, NULL); } FOREACHneighbor_(facet) { - angle= qh_getangle (facet->normal, neighbor->normal); + angle= qh_getangle(facet->normal, neighbor->normal); minimize_( minangle, angle); } } @@ -1791,24 +1796,19 @@ void qh_initialhull(setT *vertices) { realT diff= 1.0 + minangle; qh NARROWhull= True; - qh_option ("_narrow-hull", NULL, &diff); + qh_option("_narrow-hull", NULL, &diff); if (minangle < qh_WARNnarrow && !qh RERUN && qh PRINTprecision) - fprintf (qh ferr, "qhull precision warning: \n\ -The initial hull is narrow (cosine of min. angle is %.16f).\n\ -A coplanar point may lead to a wide facet. Options 'QbB' (scale to unit box)\n\ -or 'Qbb' (scale last coordinate) may remove this warning. Use 'Pp' to skip\n\ -this warning. See 'Limitations' in qh-impre.htm.\n", - -minangle); /* convert from angle between normals to angle between facets */ + qh_printhelp_narrowhull(qh ferr, minangle); } zzval_(Zprocessed)= qh hull_dim+1; - qh_checkpolygon (qh facet_list); + qh_checkpolygon(qh facet_list); qh_checkconvex(qh facet_list, qh_DATAfault); #ifndef qh_NOtrace if (qh IStracing >= 1) { - fprintf(qh ferr, "qh_initialhull: simplex constructed, interior point:"); + qh_fprintf(qh ferr, 8105, "qh_initialhull: simplex constructed, interior point:"); for (k=0; k < qh hull_dim; k++) - fprintf (qh ferr, " %6.4g", qh interior_point[k]); - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 8106, " %6.4g", qh interior_point[k]); + qh_fprintf(qh ferr, 8107, "\n"); } #endif } /* initialhull */ @@ -1838,69 +1838,69 @@ setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints int index, point_i, point_n, k; boolT nearzero= False; - vertices= qh_settemp (dim + 1); - simplex= qh_settemp (dim+1); + vertices= qh_settemp(dim + 1); + simplex= qh_settemp(dim+1); if (qh ALLpoints) - qh_maxsimplex (dim, NULL, points, numpoints, &simplex); + qh_maxsimplex(dim, NULL, points, numpoints, &simplex); else if (qh RANDOMoutside) { - while (qh_setsize (simplex) != dim+1) { + while (qh_setsize(simplex) != dim+1) { randr= qh_RANDOMint; randr= randr/(qh_RANDOMmax+1); index= (int)floor(qh num_points * randr); - while (qh_setin (simplex, qh_point (index))) { + while (qh_setin(simplex, qh_point(index))) { index++; /* in case qh_RANDOMint always returns the same value */ index= index < qh num_points ? index : 0; } - qh_setappend (&simplex, qh_point (index)); + qh_setappend(&simplex, qh_point(index)); } }else if (qh hull_dim >= qh_INITIALmax) { - tested= qh_settemp (dim+1); - qh_setappend (&simplex, SETfirst_(maxpoints)); /* max and min X coord */ - qh_setappend (&simplex, SETsecond_(maxpoints)); - qh_maxsimplex (fmin_(qh_INITIALsearch, dim), maxpoints, points, numpoints, &simplex); - k= qh_setsize (simplex); + 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)){ + if (!qh_setin(simplex, point) && !qh_setin(tested, point)){ qh_detsimplex(point, simplex, k, &nearzero); if (nearzero) - qh_setappend (&tested, point); + qh_setappend(&tested, point); else { - qh_setappend (&simplex, point); + 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); + 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); + qh_setappend(&tested, point); else { - qh_setappend (&simplex, point); + qh_setappend(&simplex, point); k++; } } } index= 0; - while (k != dim && (point= qh_point (index++))) { - if (!qh_setin (simplex, point) && !qh_setin (tested, point)){ - qh_detsimplex (point, simplex, k, &nearzero); + while (k != dim && (point= qh_point(index++))) { + if (!qh_setin(simplex, point) && !qh_setin(tested, point)){ + qh_detsimplex(point, simplex, k, &nearzero); if (!nearzero){ - qh_setappend (&simplex, point); + qh_setappend(&simplex, point); k++; } } } - qh_settempfree (&tested); - qh_maxsimplex (dim, maxpoints, points, numpoints, &simplex); + qh_settempfree(&tested); + qh_maxsimplex(dim, maxpoints, points, numpoints, &simplex); }else - qh_maxsimplex (dim, maxpoints, points, numpoints, &simplex); + qh_maxsimplex(dim, maxpoints, points, numpoints, &simplex); FOREACHpoint_(simplex) - qh_setaddnth (&vertices, 0, qh_newvertex(point)); /* descending order */ - qh_settempfree (&simplex); + qh_setaddnth(&vertices, 0, qh_newvertex(point)); /* descending order */ + qh_settempfree(&simplex); return vertices; } /* initialvertices */ @@ -1914,7 +1914,7 @@ setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints notes: for qh.GOODvertex */ -vertexT *qh_isvertex (pointT *point, setT *vertices) { +vertexT *qh_isvertex(pointT *point, setT *vertices) { vertexT *vertex, **vertexp; FOREACHvertex_(vertices) { @@ -1946,7 +1946,7 @@ vertexT *qh_isvertex (pointT *point, setT *vertices) { see also: qh_makenewplanes() -- make hyperplanes for facets - qh_attachnewfacets() -- attachnewfacets if not done here (qh ONLYgood) + 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 @@ -1959,7 +1959,7 @@ vertexT *qh_isvertex (pointT *point, setT *vertices) { update its f.replace clear its neighbor set */ -vertexT *qh_makenewfacets (pointT *point /*visible_list*/) { +vertexT *qh_makenewfacets(pointT *point /*visible_list*/) { facetT *visible, *newfacet= NULL, *newfacet2= NULL, *neighbor, **neighborp; vertexT *apex; int numnew=0; @@ -1967,7 +1967,7 @@ vertexT *qh_makenewfacets (pointT *point /*visible_list*/) { qh newfacet_list= qh facet_tail; qh newvertex_list= qh vertex_tail; apex= qh_newvertex(point); - qh_appendvertex (apex); + qh_appendvertex(apex); qh visit_id++; if (!qh ONLYgood) qh NEWfacets= True; @@ -1976,10 +1976,10 @@ vertexT *qh_makenewfacets (pointT *point /*visible_list*/) { neighbor->seen= False; if (visible->ridges) { visible->visitid= qh visit_id; - newfacet2= qh_makenew_nonsimplicial (visible, apex, &numnew); + newfacet2= qh_makenew_nonsimplicial(visible, apex, &numnew); } if (visible->simplicial) - newfacet= qh_makenew_simplicial (visible, apex, &numnew); + newfacet= qh_makenew_simplicial(visible, apex, &numnew); if (!qh ONLYgood) { if (newfacet2) /* newfacet is null if all ridges defined */ newfacet= newfacet2; @@ -1990,10 +1990,10 @@ vertexT *qh_makenewfacets (pointT *point /*visible_list*/) { SETfirst_(visible->neighbors)= NULL; } } - trace1((qh ferr, "qh_makenewfacets: created %d new facets from point p%d to horizon\n", + 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); + qh_printfacetlist(qh newfacet_list, NULL, qh_ALL); return apex; } /* makenewfacets */ @@ -2027,16 +2027,16 @@ vertexT *qh_makenewfacets (pointT *point /*visible_list*/) { make best match (it will not be merged) */ #ifndef qh_NOmerge -void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount) { +void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount) { boolT same, ismatch; int hash, scan; facetT *facet, *newfacet, *maxmatch= NULL, *maxmatch2= NULL, *nextfacet; int skip, newskip, nextskip= 0, maxskip= 0, maxskip2= 0, makematch; realT maxdist= -REALmax, mindist, dist2, low, high; - hash= (int)qh_gethash (hashsize, atfacet->vertices, qh hull_dim, 1, + hash= (int)qh_gethash(hashsize, atfacet->vertices, qh hull_dim, 1, SETelem_(atfacet->vertices, atskip)); - trace2((qh ferr, "qh_matchduplicates: find duplicate matches for f%d skip %d hash %d hashcount %d\n", + 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++; @@ -2049,11 +2049,11 @@ void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcou if (!facet->dupridge || facet->visitid == qh visit_id) continue; zinc_(Zhashtests); - if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) { + if (qh_matchvertices(1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) { ismatch= (same == (newfacet->toporient ^ facet->toporient)); if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) { if (!makematch) { - fprintf (qh ferr, "qhull internal error (qh_matchduplicates): missing dupridge at f%d skip %d for new f%d skip %d hash %d\n", + 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); } @@ -2065,12 +2065,12 @@ void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcou else SETelem_(newfacet->neighbors, newskip)= qh_MERGEridge; *hashcount -= 2; /* removed two unmatched facets */ - trace4((qh ferr, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d merge\n", + 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); + mindist= qh_getdistance(facet, newfacet, &low, &high); + dist2= qh_getdistance(newfacet, facet, &low, &high); minimize_(mindist, dist2); if (mindist > maxdist) { maxdist= mindist; @@ -2079,7 +2079,7 @@ void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcou maxmatch2= newfacet; maxskip2= newskip; } - trace3((qh ferr, "qh_matchduplicates: duplicate f%d skip %d new f%d skip %d at dist %2.2g, max is now f%d f%d\n", + 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 */ @@ -2089,27 +2089,27 @@ void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcou } if (makematch && !facet && SETelemt_(facet->neighbors, skip, facetT) == qh_DUPLICATEridge) { - fprintf (qh ferr, "qhull internal error (qh_matchduplicates): no MERGEridge match for duplicate f%d skip %d at hash %d\n", + 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); + qh_errexit(qh_ERRqhull, newfacet, NULL); } } } /* end of for each new facet at hash */ if (!makematch) { if (!maxmatch) { - fprintf (qh ferr, "qhull internal error (qh_matchduplicates): no maximum match at duplicate f%d skip %d at hash %d\n", + 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); + qh_errexit(qh_ERRqhull, atfacet, NULL); } SETelem_(maxmatch->neighbors, maxskip)= maxmatch2; SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch; *hashcount -= 2; /* removed two unmatched facets */ zzinc_(Zmultiridge); - trace0((qh ferr, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d keep\n", + 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"); + qh_precision("ridge with multiple neighbors"); if (qh IStracing >= 4) - qh_errprint ("DUPLICATED/MATCH", maxmatch, maxmatch2, NULL, NULL); + qh_errprint("DUPLICATED/MATCH", maxmatch, maxmatch2, NULL, NULL); } } } /* matchduplicates */ @@ -2137,7 +2137,7 @@ void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcou else if not keeping both coplanar and inside points remove !coplanar or !inside points from coplanar sets */ -void qh_nearcoplanar ( void /* qh.facet_list */) { +void qh_nearcoplanar(void /* qh.facet_list */) { facetT *facet; pointT *point, **pointp; int numpart; @@ -2149,22 +2149,22 @@ void qh_nearcoplanar ( void /* qh.facet_list */) { qh_setfree( &facet->coplanarset); } }else if (!qh KEEPcoplanar || !qh KEEPinside) { - qh_outerinner (NULL, NULL, &innerplane); + qh_outerinner(NULL, NULL, &innerplane); if (qh JOGGLEmax < REALmax/2) - innerplane -= qh JOGGLEmax * sqrt (qh hull_dim); + innerplane -= qh JOGGLEmax * sqrt((realT)qh hull_dim); numpart= 0; FORALLfacets { if (facet->coplanarset) { FOREACHpoint_(facet->coplanarset) { numpart++; - qh_distplane (point, facet, &dist); + 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); + qh_setcompact(facet->coplanarset); } } zzadd_(Zcheckpart, numpart); @@ -2187,7 +2187,7 @@ void qh_nearcoplanar ( void /* qh.facet_list */) { 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) { +vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp) { realT bestdist= REALmax, dist; vertexT *bestvertex= NULL, *vertex, **vertexp, *apex; coordT *center; @@ -2199,11 +2199,11 @@ vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp) { dim--; if (facet->tricoplanar) { if (!qh VERTEXneighbors || !facet->center) { - fprintf(qh ferr, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n"); + qh_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= SETfirst_(facet->vertices); + vertices= qh_settemp(qh TEMPsize); + apex= SETfirstt_(facet->vertices, vertexT); center= facet->center; FOREACHneighbor_(apex) { if (neighbor->center == center) { @@ -2214,16 +2214,16 @@ vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp) { }else vertices= facet->vertices; FOREACHvertex_(vertices) { - dist= qh_pointdist (vertex->point, point, -dim); + 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, "qh_nearvertex: v%d dist %2.2g for f%d p%d\n", + 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 */ @@ -2249,8 +2249,8 @@ int qh_newhashtable(int newsize) { 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); + qh hash_table= qh_setnew(size); + qh_setzero(qh hash_table, 0, size); return size; } /* newhashtable */ @@ -2265,9 +2265,9 @@ vertexT *qh_newvertex(pointT *point) { zinc_(Ztotvertices); vertex= (vertexT *)qh_memalloc(sizeof(vertexT)); - memset ((char *) vertex, 0, sizeof (vertexT)); + memset((char *) vertex, 0, sizeof(vertexT)); if (qh vertex_id == 0xFFFFFF) { - fprintf(qh ferr, "qhull input error: more than %d vertices. ID field overflows and two vertices\n\ + qh_fprintf(qh ferr, 6159, "qhull input error: more than %d vertices. ID field overflows and two vertices\n\ may have the same identifier. Vertices not sorted correctly.\n", 0xFFFFFF); qh_errexit(qh_ERRinput, NULL, NULL); } @@ -2275,9 +2275,10 @@ may have the same identifier. Vertices not sorted correctly.\n", 0xFFFFFF); qh tracevertex= vertex; vertex->id= qh vertex_id++; vertex->point= point; - trace4((qh ferr, "qh_newvertex: vertex p%d (v%d) created\n", qh_pointid(vertex->point), + vertex->dim= (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); + return(vertex); } /* newvertex */ /*-<a href="qh-poly.htm#TOC" @@ -2285,17 +2286,21 @@ may have the same identifier. Vertices not sorted correctly.\n", 0xFFFFFF); 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) { +ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) { vertexT *atvertex, *vertex, *othervertex; ridgeT *ridge, **ridgep; @@ -2322,9 +2327,9 @@ ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) { return NULL; } /* nextridge3d */ #else /* qh_NOmerge */ -void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount) { +void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount) { } -ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) { +ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) { return NULL; } @@ -2344,22 +2349,22 @@ ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) { for each outside point for facet partition point into coplanar set */ -void qh_outcoplanar (void /* facet_list */) { +void qh_outcoplanar(void /* facet_list */) { pointT *point, **pointp; facetT *facet; realT dist; - trace1((qh ferr, "qh_outcoplanar: move outsideset to coplanarset for qh NARROWhull\n")); + 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); + qh_distplane(point, facet, &dist); zinc_(Zpartition); - qh_partitioncoplanar (point, facet, &dist); + qh_partitioncoplanar(point, facet, &dist); } } - qh_setfree (&facet->outsideset); + qh_setfree(&facet->outsideset); } } /* outcoplanar */ @@ -2370,17 +2375,17 @@ void qh_outcoplanar (void /* facet_list */) { return point for a point id, or NULL if unknown alternative code: - return ((pointT *)((unsigned long)qh.first_point + return((pointT *)((unsigned long)qh.first_point + (unsigned long)((id)*qh.normal_size))); */ -pointT *qh_point (int id) { +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)) + if (id < qh_setsize(qh other_points)) return SETelemt_(qh other_points, id, pointT); return NULL; } /* point */ @@ -2397,17 +2402,17 @@ pointT *qh_point (int id) { notes: checks point.id */ -void qh_point_add (setT *set, pointT *point, void *elem) { +void qh_point_add(setT *set, pointT *point, void *elem) { int id, size; SETreturnsize_(set, size); if ((id= qh_pointid(point)) < 0) - fprintf (qh ferr, "qhull internal warning (point_add): unknown point %p id %d\n", + qh_fprintf(qh ferr, 7067, "qhull internal warning (point_add): unknown point %p id %d\n", point, id); else if (id >= size) { - fprintf (qh ferr, "qhull internal errror (point_add): point p%d is out of bounds (%d)\n", + 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); + qh_errexit(qh_ERRqhull, NULL, NULL); }else SETelem_(set, id)= elem; } /* point_add */ @@ -2437,27 +2442,27 @@ void qh_point_add (setT *set, pointT *point, void *elem) { 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 *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); + 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); + qh_point_add(facets, vertex->point, facet); } } FOREACHpoint_(facet->coplanarset) - qh_point_add (facets, point, facet); + qh_point_add(facets, point, facet); FOREACHpoint_(facet->outsideset) - qh_point_add (facets, point, facet); + qh_point_add(facets, point, facet); } return facets; } /* pointfacet */ @@ -2474,15 +2479,15 @@ setT *qh_pointfacet (void /*qh facet_list*/) { FOREACHvertex_i_(vertices) { ... } SETelem_(vertices, i) */ -setT *qh_pointvertex (void /*qh facet_list*/) { - int numpoints= qh num_points + qh_setsize (qh other_points); +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); + vertices= qh_settemp(numpoints); + qh_setzero(vertices, 0, numpoints); FORALLvertices - qh_point_add (vertices, vertex->point, vertex); + qh_point_add(vertices, vertex->point, vertex); return vertices; } /* pointvertex */ @@ -2505,7 +2510,7 @@ void qh_prependfacet(facetT *facet, facetT **facetlist) { facetT *prevfacet, *list; - trace4((qh ferr, "qh_prependfacet: prepend f%d before f%d\n", + trace4((qh ferr, 4061, "qh_prependfacet: prepend f%d before f%d\n", facet->id, getid_(*facetlist))); if (!*facetlist) (*facetlist)= qh facet_tail; @@ -2553,10 +2558,10 @@ void qh_printhashtable(FILE *fp) { } if (neighbor_i == neighbor_n) continue; - fprintf (fp, "hash %d f%d ", facet_i, facet->id); + qh_fprintf(fp, 9283, "hash %d f%d ", facet_i, facet->id); FOREACHvertex_(facet->vertices) - fprintf (fp, "v%d ", vertex->id); - fprintf (fp, "\n neighbors:"); + qh_fprintf(fp, 9284, "v%d ", vertex->id); + qh_fprintf(fp, 9285, "\n neighbors:"); FOREACHneighbor_i_(facet) { if (neighbor == qh_MERGEridge) id= -3; @@ -2564,9 +2569,9 @@ void qh_printhashtable(FILE *fp) { id= -2; else id= getid_(neighbor); - fprintf (fp, " %d", id); + qh_fprintf(fp, 9286, " %d", id); } - fprintf (fp, "\n"); + qh_fprintf(fp, 9287, "\n"); } } } /* printhashtable */ @@ -2578,27 +2583,27 @@ void qh_printhashtable(FILE *fp) { qh_printlists( fp ) print out facet and vertex list for debugging (without 'f/v' tags) */ -void qh_printlists (void) { +void qh_printlists(void) { facetT *facet; vertexT *vertex; int count= 0; - fprintf (qh ferr, "qh_printlists: facets:"); + qh_fprintf(qh ferr, 8108, "qh_printlists: facets:"); FORALLfacets { if (++count % 100 == 0) - fprintf (qh ferr, "\n "); - fprintf (qh ferr, " %d", facet->id); + qh_fprintf(qh ferr, 8109, "\n "); + qh_fprintf(qh ferr, 8110, " %d", facet->id); } - fprintf (qh ferr, "\n new facets %d visible facets %d next facet for qh_addpoint %d\n vertices (new %d):", + 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) - fprintf (qh ferr, "\n "); - fprintf (qh ferr, " %d", vertex->id); + qh_fprintf(qh ferr, 8112, "\n "); + qh_fprintf(qh ferr, 8113, " %d", vertex->id); } - fprintf (qh ferr, "\n"); + qh_fprintf(qh ferr, 8114, "\n"); } /* printlists */ /*-<a href="qh-poly.htm#TOC" @@ -2612,7 +2617,7 @@ void qh_printlists (void) { returns: visible_list is empty if qh_deletevisible was called */ -void qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/) { +void qh_resetlists(boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/) { vertexT *vertex; facetT *newfacet, *visible; int totnew=0, totver=0; @@ -2662,16 +2667,16 @@ void qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet FORALLvertices {...} to locate the vertex for a point. FOREACHneighbor_(vertex) {...} to visit the Voronoi centers for a Voronoi cell. */ -void qh_setvoronoi_all (void) { +void qh_setvoronoi_all(void) { facetT *facet; - qh_clearcenters (qh_ASvoronoi); + qh_clearcenters(qh_ASvoronoi); qh_vertexneighbors(); FORALLfacets { if (!facet->normal || !facet->upperdelaunay || qh UPPERdelaunay) { if (!facet->center) - facet->center= qh_facetcenter (facet->vertices); + facet->center= qh_facetcenter(facet->vertices); } } } /* setvoronoi_all */ @@ -2683,7 +2688,8 @@ void qh_setvoronoi_all (void) { qh_triangulate() triangulate non-simplicial facets on qh.facet_list, - if qh.CENTERtype=qh_ASvoronoi, sets Voronoi centers of non-simplicial facets + if qh VORONOI, sets Voronoi centers of non-simplicial facets + nop if hasTriangulation returns: all facets simplicial @@ -2693,7 +2699,7 @@ void qh_setvoronoi_all (void) { 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*/) { +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; @@ -2703,17 +2709,19 @@ void qh_triangulate (void /*qh facet_list*/) { mergeType mergetype; int neighbor_i, neighbor_n; - trace1((qh ferr, "qh_triangulate: triangulate non-simplicial facets\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_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 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; @@ -2722,46 +2730,46 @@ void qh_triangulate (void /*qh facet_list*/) { /* 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); + qh_triangulate_facet(facet, &new_vertex_list); } - trace2((qh ferr, "qh_triangulate: delete null facets from f%d -- apex same as second vertex\n", getid_(new_facet_list))); + 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) { - fprintf( qh ferr, "qhull error (qh_triangulate): ridges still defined for f%d\n", facet->id); - qh_errexit (qh_ERRqhull, facet, NULL); + 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); + qh_setfree(&facet->ridges); } if (SETfirst_(facet->vertices) == SETsecond_(facet->vertices)) { zinc_(Ztrinull); - qh_triangulate_null (facet); + qh_triangulate_null(facet); } } - trace2((qh ferr, "qh_triangulate: delete %d or more mirror facets -- same vertices and neighbors\n", qh_setsize(qh degen_mergeset))); + 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))) { + while ((merge= (mergeT*)qh_setdellast(qh degen_mergeset))) { facet1= merge->facet1; facet2= merge->facet2; mergetype= merge->type; - qh_memfree (merge, sizeof(mergeT)); + qh_memfree(merge, sizeof(mergeT)); if (mergetype == MRGmirror) { zinc_(Ztrimirror); - qh_triangulate_mirror (facet1, facet2); + qh_triangulate_mirror(facet1, facet2); } } qh_settempfree(&qh degen_mergeset); - trace2((qh ferr, "qh_triangulate: update neighbor lists for vertices from v%d\n", getid_(new_vertex_list))); + 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*/); + qh_resetlists(False, !qh_RESETvisible /*qh newvertex_list, empty newfacet_list and visible_list*/); - trace2((qh ferr, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list))); - trace2((qh ferr, "qh_triangulate: and replace facet->f.triowner with tricoplanar facets that own center, normal, etc.\n")); + 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) { @@ -2785,7 +2793,7 @@ void qh_triangulate (void /*qh facet_list*/) { } } - trace2((qh ferr, "qh_triangulate: delete visible facets -- non-simplicial, null, and mirrored facets\n")); + 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 */ @@ -2797,7 +2805,7 @@ void qh_triangulate (void /*qh facet_list*/) { }else { /* a non-simplicial facet followed by its tricoplanars */ if (visible && !owner) { /* RBOX 200 s D5 t1001471447 | QHULL Qt C-0.01 Qx Qc Tv Qt -- f4483 had 6 vertices/neighbors and 8 ridges */ - trace2((qh ferr, "qh_triangulate: all tricoplanar facets degenerate for non-simplicial facet f%d\n", + 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--; @@ -2807,7 +2815,7 @@ void qh_triangulate (void /*qh facet_list*/) { } }else if (facet->tricoplanar) { if (facet->f.triowner != visible) { - fprintf( qh ferr, "qhull error (qh_triangulate): tricoplanar facet f%d not owned by its visible, non-simplicial facet f%d\n", facet->id, getid_(visible)); + qh_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) @@ -2830,7 +2838,7 @@ void qh_triangulate (void /*qh facet_list*/) { } } if (visible && !owner) { - trace2((qh ferr, "qh_triangulate: all tricoplanar facets degenerate for last non-simplicial facet f%d\n", + 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--; @@ -2838,14 +2846,15 @@ void qh_triangulate (void /*qh facet_list*/) { qh NEWfacets= False; qh ONLYgood= onlygood; /* restore value */ if (qh CHECKfrequently) - qh_checkpolygon (qh facet_list); + 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) + qh_triangulate_facet(facetA) triangulate a non-simplicial facet if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center returns: @@ -2872,29 +2881,29 @@ void qh_triangulate (void /*qh facet_list*/) { copy facet->center, normal, offset update vertex neighbors */ -void qh_triangulate_facet (facetT *facetA, vertexT **first_vertex) { +void qh_triangulate_facet(facetT *facetA, vertexT **first_vertex) { facetT *newfacet; facetT *neighbor, **neighborp; vertexT *apex; int numnew=0; - trace3((qh ferr, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id)); + trace3((qh ferr, 3020, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id)); if (qh IStracing >= 4) - qh_printfacet (qh ferr, facetA); + 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); + facetA->center= qh_facetcenter(facetA->vertices); } - qh_willdelete (facetA, NULL); + qh_willdelete(facetA, NULL); qh newfacet_list= qh facet_tail; facetA->visitid= qh visit_id; - apex= SETfirst_(facetA->vertices); - qh_makenew_nonsimplicial (facetA, apex, &numnew); + apex= SETfirstt_(facetA->vertices, vertexT); + qh_makenew_nonsimplicial(facetA, apex, &numnew); SETfirst_(facetA->neighbors)= NULL; FORALLnew_facets { newfacet->tricoplanar= True; @@ -2904,11 +2913,11 @@ void qh_triangulate_facet (facetT *facetA, vertexT **first_vertex) { newfacet->good= facetA->good; if (qh TRInormals) { newfacet->keepcentrum= True; - newfacet->normal= qh_copypoints (facetA->normal, 1, qh hull_dim); + newfacet->normal= qh_copypoints(facetA->normal, 1, qh hull_dim); if (qh CENTERtype == qh_AScentrum) - newfacet->center= qh_getcentrum (newfacet); + newfacet->center= qh_getcentrum(newfacet); else - newfacet->center= qh_copypoints (facetA->center, 1, qh hull_dim); + newfacet->center= qh_copypoints(facetA->center, 1, qh hull_dim); }else { newfacet->keepcentrum= False; newfacet->normal= facetA->normal; @@ -2928,70 +2937,70 @@ void qh_triangulate_facet (facetT *facetA, vertexT **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*/); + 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) + 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) { +void qh_triangulate_link(facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB) { int errmirror= False; - trace3((qh ferr, "qh_triangulate_link: relink old facets f%d and f%d between neighbors f%d and f%d\n", + 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)) + 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)) + qh_appendmergeset(facetA, facetB, MRGmirror, NULL); + }else if (qh_setin(facetB->neighbors, facetA)) errmirror= True; if (errmirror) { - fprintf( qh ferr, "qhull error (qh_triangulate_link): mirror facets f%d and f%d do not match for old facets f%d and f%d\n", + 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); + 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) + 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) { +void qh_triangulate_mirror(facetT *facetA, facetT *facetB) { facetT *neighbor, *neighborB; int neighbor_i, neighbor_n; - trace3((qh ferr, "qh_triangulate_mirror: delete mirrored facets f%d and f%d\n", + 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_triangulate_link(facetA, neighbor, facetB, neighborB); } - qh_willdelete (facetA, NULL); - qh_willdelete (facetB, NULL); + 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) + qh_triangulate_null(facetA) remove null facetA from qh_triangulate_facet() a null facet has vertex #1 (apex) == vertex #2 returns: @@ -3001,18 +3010,18 @@ void qh_triangulate_mirror (facetT *facetA, facetT *facetB) { 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) { +void qh_triangulate_null(facetT *facetA) { facetT *neighbor, *otherfacet; - trace3((qh ferr, "qh_triangulate_null: delete null facet f%d\n", facetA->id)); - neighbor= SETfirst_(facetA->neighbors); - otherfacet= SETsecond_(facetA->neighbors); - qh_triangulate_link (facetA, neighbor, facetA, otherfacet); - qh_willdelete (facetA, NULL); + 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) { +void qh_triangulate(void) { } #endif /* qh_NOmerge */ @@ -3032,10 +3041,10 @@ void qh_triangulate (void) { void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB) { setT *intersection; - intersection= qh_vertexintersect_new (*vertexsetA, vertexsetB); - qh_settempfree (vertexsetA); + intersection= qh_vertexintersect_new(*vertexsetA, vertexsetB); + qh_settempfree(vertexsetA); *vertexsetA= intersection; - qh_settemppush (intersection); + qh_settemppush(intersection); } /* vertexintersect */ /*-<a href="qh-poly.htm#TOC" @@ -3047,8 +3056,8 @@ void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB) { returns: a new set */ -setT *qh_vertexintersect_new (setT *vertexsetA,setT *vertexsetB) { - setT *intersection= qh_setnew (qh hull_dim - 1); +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); @@ -3086,13 +3095,13 @@ setT *qh_vertexintersect_new (setT *vertexsetA,setT *vertexsetB) { for each vertex append facet to vertex->neighbors */ -void qh_vertexneighbors (void /*qh facet_list*/) { +void qh_vertexneighbors(void /*qh facet_list*/) { facetT *facet; vertexT *vertex, **vertexp; if (qh VERTEXneighbors) return; - trace1((qh ferr, "qh_vertexneighbors: determing neighboring facets for each vertex\n")); + trace1((qh ferr, 1035, "qh_vertexneighbors: determing neighboring facets for each vertex\n")); qh vertex_visit++; FORALLfacets { if (facet->visible) @@ -3100,9 +3109,9 @@ void qh_vertexneighbors (void /*qh facet_list*/) { FOREACHvertex_(facet->vertices) { if (vertex->visitid != qh vertex_visit) { vertex->visitid= qh vertex_visit; - vertex->neighbors= qh_setnew (qh hull_dim); + vertex->neighbors= qh_setnew(qh hull_dim); } - qh_setappend (&vertex->neighbors, facet); + qh_setappend(&vertex->neighbors, facet); } } qh VERTEXneighbors= True; diff --git a/src/qconvex.c b/src/qconvex.c index dbd8933..9653f9e 100644 --- a/src/qconvex.c +++ b/src/qconvex.c @@ -6,7 +6,7 @@ see unix.c for full interface - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2008, The Geometry Center */ #include <stdio.h> @@ -14,7 +14,7 @@ #include <string.h> #include <ctype.h> #include <math.h> -#include "qhull.h" +#include "qhulllib.h" #include "mem.h" #include "qset.h" @@ -26,7 +26,7 @@ #elif __cplusplus extern "C" { - int isatty (int); + int isatty(int); } #elif _MSC_VER @@ -34,7 +34,7 @@ extern "C" { #define isatty _isatty #else -int isatty (int); /* returns 1 if stdin is a tty +int isatty(int); /* returns 1 if stdin is a tty if "Undefined symbol" this can be deleted along with call in main() */ #endif @@ -45,7 +45,7 @@ int isatty (int); /* returns 1 if stdin is a tty long prompt for qconvex notes: - restricted version of qhull.c + restricted version of qhulllib.c see: concise prompt below @@ -142,7 +142,7 @@ More formats:\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\ + #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\ @@ -281,10 +281,10 @@ int main(int argc, char *argv[]) { 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"); + 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 @@ -301,17 +301,17 @@ int main(int argc, char *argv[]) { 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(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 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_option("Qxact_merge", NULL, NULL); qh MERGEexact= True; /* 'Qx' always */ } - qh_init_B (points, numpoints, dim, ismalloc); + qh_init_B(points, numpoints, dim, ismalloc); qh_qhull(); qh_check_output(); qh_produce_output(); @@ -324,9 +324,9 @@ int main(int argc, char *argv[]) { qh_freeqhull( True); #else qh_freeqhull( False); - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) - fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", + fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); #endif return exitcode; diff --git a/src/qdelaun.c b/src/qdelaun.c index 68620fa..f5f9f49 100644 --- a/src/qdelaun.c +++ b/src/qdelaun.c @@ -7,7 +7,7 @@ see unix.c for full interface - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2008, The Geometry Center */ #include <stdio.h> @@ -15,7 +15,7 @@ #include <string.h> #include <ctype.h> #include <math.h> -#include "qhull.h" +#include "qhulllib.h" #include "mem.h" #include "qset.h" @@ -27,7 +27,7 @@ #elif __cplusplus extern "C" { - int isatty (int); + int isatty(int); } #elif _MSC_VER @@ -35,7 +35,7 @@ extern "C" { #define isatty _isatty #else -int isatty (int); /* returns 1 if stdin is a tty +int isatty(int); /* returns 1 if stdin is a tty if "Undefined symbol" this can be deleted along with call in main() */ #endif @@ -46,7 +46,7 @@ int isatty (int); /* returns 1 if stdin is a tty long prompt for qhull notes: - restricted version of qhull.c + restricted version of qhulllib.c see: concise prompt below @@ -133,7 +133,7 @@ More formats:\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\ + #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\ @@ -267,10 +267,10 @@ int main(int argc, char *argv[]) { 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"); + 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 @@ -287,21 +287,21 @@ int main(int argc, char *argv[]) { 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(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_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_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_option("Qxact_merge", NULL, NULL); qh MERGEexact= True; /* 'Qx' always */ } - qh_init_B (points, numpoints, dim, ismalloc); + qh_init_B(points, numpoints, dim, ismalloc); qh_qhull(); qh_check_output(); qh_produce_output(); @@ -314,9 +314,9 @@ int main(int argc, char *argv[]) { qh_freeqhull( True); #else qh_freeqhull( False); - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) - fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", + fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); #endif return exitcode; diff --git a/src/qh-geom.htm b/src/qh-geom.htm index a2f100c..908502c 100644 --- a/src/qh-geom.htm +++ b/src/qh-geom.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</a><br> +<b>Up:</b> <a href="../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br> <b>To:</b> <a href="../src/index.htm">Qhull functions</a>, macros, and data structures<br> <b>To:</b> <a href="qh-geom.htm#TOC">Geom</a> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -32,7 +32,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> <hr> <!-- Main text of document. --> -<h2>geom.c, geom2.c -- geometric and floating point routines</h2> +<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 @@ -64,7 +64,9 @@ distance from vertices to the halfspace. </p> <a href="qh-stat.htm#TOC">Stat</a> • <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>, and <a href="geom.h">geom.h</a></h3> +<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> @@ -81,9 +83,9 @@ distance from vertices to the halfspace. </p> and constants</a></h3> <ul> -<li><a href="qhull.h#coordT">coordT</a> coordinates and +<li><a href="qhulllib.h#coordT">coordT</a> coordinates and coefficients are stored as realT</li> -<li><a href="qhull.h#pointT">pointT</a> a point is an array +<li><a href="qhulllib.h#pointT">pointT</a> a point is an array of <tt>DIM3</tt> coordinates </li> </ul> @@ -133,11 +135,11 @@ vector </li> 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="geom2.c#rand">qh_rand/srand</a> generate random +<li><a href="random.c#rand">qh_rand/srand</a> generate random numbers </li> -<li><a href="geom2.c#randomfactor">qh_randomfactor</a> return +<li><a href="random.c#randomfactor">qh_randomfactor</a> return a random factor near 1.0 </li> -<li><a href="geom2.c#randommatrix">qh_randommatrix</a> +<li><a href="random.c#randommatrix">qh_randommatrix</a> generate a random dimXdim matrix in range (-1,1) </li> </ul> @@ -269,7 +271,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-globa.htm b/src/qh-globa.htm index 723912e..3c07569 100644 --- a/src/qh-globa.htm +++ b/src/qh-globa.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm#TOC">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -42,7 +42,7 @@ dynamically allocated with malloc(). See <a href="user.h#QHpointer">QHpointer</a>. </p> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <b>Global</b> • @@ -52,7 +52,7 @@ dynamically allocated with malloc(). See <a href="qh-stat.htm#TOC">Stat</a> • <a href="qh-user.htm#TOC">User</a> </p> <h3>Index to <a href="global.c">global.c</a> and -<a href="qhull.h">qhull.h</a></h3> +<a href="qhulllib.h">qhulllib.h</a></h3> <ul> <li><a href="#ovar">Qhull's global variables</a> </li> @@ -65,24 +65,24 @@ variables</a></h3> <ul> <li><a href=global.c#qh_version>qh_version</a> version string -<li><a href="qhull.h#qh">qh</a> all global variables for +<li><a href="qhulllib.h#qh">qh</a> all global variables for qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li> -<li><a href="qhull.h#qh-const">qh constants</a> configuration +<li><a href="qhulllib.h#qh-const">qh constants</a> configuration flags and constants for Qhull </li> -<li><a href="qhull.h#qh-prec">qh precision constants</a> +<li><a href="qhulllib.h#qh-prec">qh precision constants</a> precision constants for Qhull </li> -<li><a href="qhull.h#qh-intern">qh internal constants</a> +<li><a href="qhulllib.h#qh-codetern">qh internal constants</a> internal constants for Qhull </li> -<li><a href="qhull.h#qh-lists">qh facet and vertex lists</a> +<li><a href="qhulllib.h#qh-lists">qh facet and vertex lists</a> lists of facets and vertices </li> -<li><a href="qhull.h#qh-var">qh global variables</a> minimum +<li><a href="qhulllib.h#qh-var">qh global variables</a> minimum and maximum distances, next visit ids, several flags, and other global variables. </li> -<li><a href="qhull.h#qh-set">qh global sets</a> global sets +<li><a href="qhulllib.h#qh-set">qh global sets</a> global sets for merging, hashing, input, etc. </li> -<li><a href="qhull.h#qh-buf">qh global buffers</a> buffers +<li><a href="qhulllib.h#qh-buf">qh global buffers</a> buffers for matrix operations and input </li> -<li><a href="qhull.h#qh-static">qh static variables</a> +<li><a href="qhulllib.h#qh-static">qh static variables</a> static variables for individual functions </li> </ul> @@ -111,6 +111,8 @@ 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> @@ -139,7 +141,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-io.htm b/src/qh-io.htm index 4218e99..b772db1 100644 --- a/src/qh-io.htm +++ b/src/qh-io.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm#TOC">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -88,22 +88,30 @@ print results of qh_printvdiagram or qh_eachvoronoi</li> <h3><a href="qh-io.htm#TOC">»</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="qhull.c#printsummary">qh_printsummary</a> print +<li><a href="qhulllib.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">»</a><a name="iprint">Print functions for all @@ -274,7 +282,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-mem.htm b/src/qh-mem.htm index 97c836b..2be8ec0 100644 --- a/src/qh-mem.htm +++ b/src/qh-mem.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm#TOC">Mem</a> @@ -40,7 +40,7 @@ from a reserved buffer. </p> <p>Use 'T5' to trace memory allocations.</p> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> • @@ -82,6 +82,7 @@ memory </li> 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> @@ -119,7 +120,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-merge.htm b/src/qh-merge.htm index e14eb2f..c69bb6a 100644 --- a/src/qh-merge.htm +++ b/src/qh-merge.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -98,7 +98,7 @@ structure.This is called a <em>redundant vertex</em>. </li> </ul> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> @@ -136,7 +136,7 @@ types, macros, and global sets</a></h3> identify a merge of two facets</li> <li><a href="merge.h#FOREACHmerge_">FOREACHmerge_</a> assign 'merge' to each merge in merges </li> -<li><a href="qhull.h#qh-set">qh global sets</a> +<li><a href="qhulllib.h#qh-set">qh global sets</a> qh.facet_mergeset contains non-convex merges while qh.degen_mergeset contains degenerate and redundant facets</li> @@ -144,7 +144,7 @@ redundant facets</li> <h3><a href="qh-merge.htm#TOC">»</a><a name="mconst">merge.h constants</a></h3> <ul> -<li><a href="qhull.h#qh-prec">qh precision constants</a> +<li><a href="qhulllib.h#qh-prec">qh precision constants</a> precision constants for Qhull </li> <li><a href="merge.h#MRG">MRG...</a> indicates the type of a merge (mergeT->type)</li> @@ -343,7 +343,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-poly.htm b/src/qh-poly.htm index 7d8a1c7..435301c 100644 --- a/src/qh-poly.htm +++ b/src/qh-poly.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -119,7 +119,7 @@ joggled input, they may have zero area or flipped orientation. </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> @@ -130,7 +130,7 @@ may have zero area or flipped orientation. </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="qhull.h">qhull.h</a></h3> +and <a href="qhulllib.h">qhulllib.h</a></h3> <ul> <li><a href="#ptype">Data types and global lists for polyhedrons</a> </li> @@ -152,15 +152,15 @@ functions</a> </li> <h3><a href="qh-poly.htm#TOC">»</a><a name="ptype">Data types and global lists for polyhedrons</a></h3> <ul> -<li><a href="qhull.h#facetT">facetT</a> defines a +<li><a href="qhulllib.h#facetT">facetT</a> defines a facet </li> -<li><a href="qhull.h#ridgeT">ridgeT</a> defines a +<li><a href="qhulllib.h#ridgeT">ridgeT</a> defines a ridge </li> -<li><a href="qhull.h#vertexT">vertexT</a> defines a +<li><a href="qhulllib.h#vertexT">vertexT</a> defines a vertex </li> -<li><a href="qhull.h#qh-lists">qh facet and vertex +<li><a href="qhulllib.h#qh-lists">qh facet and vertex lists</a> lists of facets and vertices </li> -<li><a href="qhull.h#qh-set">qh global sets</a> +<li><a href="qhulllib.h#qh-set">qh global sets</a> global sets for merging, hashing, input, etc. </li> </ul> <h3><a href="qh-poly.htm#TOC">»</a><a name="pconst">poly.h constants</a></h3> @@ -179,24 +179,24 @@ a merged ridge </li> <h3><a href="qh-poly.htm#TOC">»</a><a name="pgall">Global FORALL macros</a></h3> <ul> -<li><a href="qhull.h#FORALLfacets">FORALLfacets</a> +<li><a href="qhulllib.h#FORALLfacets">FORALLfacets</a> assign 'facet' to each facet in qh.facet_list </li> <li><a href="poly.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> assign 'visible' to each visible facet in qh.visible_list </li> -<li><a href="qhull.h#FORALLpoints">FORALLpoints</a> +<li><a href="qhulllib.h#FORALLpoints">FORALLpoints</a> assign 'point' to each point in qh.first_point, qh.num_points </li> -<li><a href="qhull.h#FORALLvertices">FORALLvertices</a> +<li><a href="qhulllib.h#FORALLvertices">FORALLvertices</a> assign 'vertex' to each vertex in qh.vertex_list </li> </ul> <h3><a href="qh-poly.htm#TOC">»</a><a name="pall">FORALL macros</a></h3> <ul> <li><a href="poly.h#FORALLfacet_">FORALLfacet_</a> assign 'facet' to each facet in facetlist </li> -<li><a href="qhull.h#FORALLpoint_">FORALLpoint_</a> +<li><a href="qhulllib.h#FORALLpoint_">FORALLpoint_</a> assign 'point' to each point in points array</li> <li><a href="poly.h#FORALLsame_">FORALLsame_</a> assign 'same' to each facet in samecycle</li> @@ -207,18 +207,18 @@ assign 'vertex' to each vertex in vertexlist </li> </ul> <h3><a href="qh-poly.htm#TOC">»</a><a name="peach">FOREACH macros</a></h3> <ul> -<li><a href="qhull.h#FOREACHfacet_">FOREACHfacet_</a> +<li><a href="qhulllib.h#FOREACHfacet_">FOREACHfacet_</a> assign 'facet' to each facet in facets </li> -<li><a href="qhull.h#FOREACHneighbor_">FOREACHneighbor_</a> +<li><a href="qhulllib.h#FOREACHneighbor_">FOREACHneighbor_</a> assign 'neighbor' to each facet in facet->neighbors or vertex->neighbors</li> <li><a href="poly.h#FOREACHnewfacet_">FOREACHnewfacet_</a> assign 'newfacet' to each facet in facet set </li> -<li><a href="qhull.h#FOREACHpoint_">FOREACHpoint_</a> +<li><a href="qhulllib.h#FOREACHpoint_">FOREACHpoint_</a> assign 'point' to each point in points set </li> -<li><a href="qhull.h#FOREACHridge_">FOREACHridge_</a> +<li><a href="qhulllib.h#FOREACHridge_">FOREACHridge_</a> assign 'ridge' to each ridge in ridge set </li> -<li><a href="qhull.h#FOREACHvertex_">FOREACHvertex_</a> +<li><a href="qhulllib.h#FOREACHvertex_">FOREACHvertex_</a> assign 'vertex' to each vertex in vertex set </li> <li><a href="poly.h#FOREACHvertexA_">FOREACHvertexA_</a> assign 'vertexA' to each vertex in vertex set</li> @@ -228,19 +228,19 @@ assign 'visible' to each facet in facet set </li> <h3><a href="qh-poly.htm#TOC">»</a><a name="pieach">Indexed FOREACH macros</a></h3> <ul> -<li><a href="qhull.h#FOREACHfacet_i_">FOREACHfacet_i_</a> +<li><a href="qhulllib.h#FOREACHfacet_i_">FOREACHfacet_i_</a> assign 'facet' and 'facet_i' to each facet in facet set </li> -<li><a href="qhull.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a> +<li><a href="qhulllib.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a> assign 'neighbor' and 'neighbor_i' to each facet in facet->neighbors or vertex->neighbors</li> -<li><a href="qhull.h#FOREACHpoint_i_">FOREACHpoint_i_</a> +<li><a href="qhulllib.h#FOREACHpoint_i_">FOREACHpoint_i_</a> assign 'point' and 'point_i' to each point in points set </li> -<li><a href="qhull.h#FOREACHridge_i_">FOREACHridge_i_</a> +<li><a href="qhulllib.h#FOREACHridge_i_">FOREACHridge_i_</a> assign 'ridge' and 'ridge_i' to each ridge in ridges set </li> -<li><a href="qhull.h#FOREACHvertex_i_">FOREACHvertex_i_</a> +<li><a href="qhulllib.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> @@ -249,9 +249,9 @@ reverse the order of first two vertices </li> </ul> <h3><a href="qh-poly.htm#TOC">»</a><a name="pmacro">Other macros for polyhedrons</a></h3> <ul> -<li><a href="qhull.h#getid_">getid_</a> return ID for +<li><a href="qhulllib.h#getid_">getid_</a> return ID for a facet, ridge, or vertex </li> -<li><a href="qhull.h#otherfacet_">otherfacet_</a> +<li><a href="qhulllib.h#otherfacet_">otherfacet_</a> return neighboring facet for a ridge in a facet </li> </ul> <h3><a href="qh-poly.htm#TOC">»</a><a name="plist">Facetlist @@ -460,7 +460,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-qhull.htm b/src/qh-qhull.htm index 037b93b..8275883 100644 --- a/src/qh-qhull.htm +++ b/src/qh-qhull.htm @@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<title>qhull.c -- top-level functions and basic data types</title> +<title>qhulllib.c -- top-level functions and basic data types</title> </head> <body> @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -30,7 +30,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> </p> <hr> -<h2>qhull.c -- top-level functions and basic data types</h2> +<h2>qhulllib.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 @@ -38,10 +38,10 @@ 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>qhull.h</tt>, +functions and base data types. The top-level header file, <tt>qhulllib.h</tt>, contains prototypes for these functions.</p> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> @@ -50,13 +50,13 @@ contains prototypes for these functions.</p> • <b>Qhull</b> • <a href="qh-set.htm#TOC">Set</a> • <a href="qh-stat.htm#TOC">Stat</a> • <a href="qh-user.htm#TOC">User</a> </p> -<h3>Index to <a href="qhull.c">qhull.c</a>, -<a href="qhull.h">qhull.h</a>, and +<h3>Index to <a href="qhulllib.c">qhulllib.c</a>, +<a href="qhulllib.h">qhulllib.h</a>, and <a href="unix.c">unix.c</a></h3> <ul> -<li><a href="#qtype">qhull.h and unix.c data types and +<li><a href="#qtype">qhulllib.h and unix.c data types and constants</a> </li> -<li><a href="#qmacro">qhull.h other macros</a> </li> +<li><a href="#qmacro">qhulllib.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> @@ -65,28 +65,30 @@ constants</a> </li> <li><a href="#qtest">Top-level routines for testing and debugging</a></li> </ul> -<h3><a href="qh-qhull.htm#TOC">»</a><a name="qtype">qhull.h and unix.c +<h3><a href="qh-qhull.htm#TOC">»</a><a name="qtype">qhulllib.h and unix.c data types and constants</a></h3> <ul> -<li><a href="qhull.h#flagT">flagT</a> Boolean flag as +<li><a href="qhulllib.h#flagT">flagT</a> Boolean flag as a bit </li> -<li><a href="qhull.h#boolT">boolT</a> boolean value, +<li><a href="qhulllib.h#boolT">boolT</a> boolean value, either True or False </li> -<li><a href="qhull.h#CENTERtype">CENTERtype</a> to +<li><a href="qhulllib.h#CENTERtype">CENTERtype</a> to distinguish facet->center </li> -<li><a href="qhull.h#qh_PRINT">qh_PRINT</a> output +<li><a href="qhulllib.h#qh_PRINT">qh_PRINT</a> output formats for printing (qh.PRINTout) </li> -<li><a href="qhull.h#qh_ALL">qh_ALL</a> argument flag +<li><a href="qhulllib.h#qh_ALL">qh_ALL</a> argument flag for selecting everything </li> -<li><a href="qhull.h#qh_ERR">qh_ERR</a> Qhull exit +<li><a href="qhulllib.h#qh_ERR">qh_ERR</a> Qhull exit codes for indicating errors </li> +<li><a href="qhulllib.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr +to distinguish error output from normal output [C++ only]</li> <li><a href="unix.c#prompt">qh_prompt</a> version and long prompt for Qhull</li> <li><a href="unix.c#prompt2">qh_prompt2</a> synopsis for Qhull</li> <li><a href="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">»</a><a name="qmacro">qhull.h other +<h3><a href="qh-qhull.htm#TOC">»</a><a name="qmacro">qhulllib.h other macros</a></h3> <ul> <li><a href="qhull_a.h#traceN">traceN</a> print trace @@ -99,34 +101,34 @@ routines in call order</a></h3> <li><a href="unix.c#main">main</a> processes the command line, calls qhull() to do the work, and exits </li> -<li><a href="qhull.c#qhull">qh_qhull</a> construct +<li><a href="qhulllib.c#qhull">qh_qhull</a> construct the convex hull of a set of points </li> -<li><a href="qhull.c#build_withrestart">qh_build_withrestart</a> +<li><a href="qhulllib.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="qhull.c#partitionall">qh_partitionall</a> +<li><a href="qhulllib.c#partitionall">qh_partitionall</a> partition all points into outside sets </li> -<li><a href="qhull.c#buildhull">qh_buildhull</a> +<li><a href="qhulllib.c#buildhull">qh_buildhull</a> construct a convex hull by adding points one at a time </li> -<li><a href="qhull.c#nextfurthest">qh_nextfurthest</a> +<li><a href="qhulllib.c#nextfurthest">qh_nextfurthest</a> return next furthest point for processing </li> -<li><a href="qhull.c#buildtracing">qh_buildtracing</a> +<li><a href="qhulllib.c#buildtracing">qh_buildtracing</a> trace an iteration of buildhull </li> -<li><a href="qhull.c#addpoint">qh_addpoint</a> add a +<li><a href="qhulllib.c#addpoint">qh_addpoint</a> add a point to the convex hull </li> -<li><a href="qhull.c#findhorizon">qh_findhorizon</a> +<li><a href="qhulllib.c#findhorizon">qh_findhorizon</a> find the horizon and visible facets for a point </li> -<li><a href="qhull.c#partitionvisible">qh_partitionvisible</a> +<li><a href="qhulllib.c#partitionvisible">qh_partitionvisible</a> partition points from facets in qh.visible_list to facets in qh.newfacet_list </li> -<li><a href="qhull.c#partitionpoint">qh_partitionpoint</a> +<li><a href="qhulllib.c#partitionpoint">qh_partitionpoint</a> partition a point as inside, coplanar with, or outside a facet </li> -<li><a href="qhull.c#partitioncoplanar">qh_partitioncoplanar</a> +<li><a href="qhulllib.c#partitioncoplanar">qh_partitioncoplanar</a> partition coplanar point into a facet </li> -<li><a href="qhull.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li> +<li><a href="qhulllib.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li> </ul> <h3><a href="qh-qhull.htm#TOC">»</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3> @@ -144,6 +146,8 @@ before error handling initialized </li> 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> @@ -177,13 +181,13 @@ point </li> <h3><a href="qh-qhull.htm#TOC">»</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3> <ul> -<li><a href="qhull.c#addpoint">qh_addpoint</a> add +<li><a href="qhulllib.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="qhull.c#qhull">qh_qhull</a> construct +<li><a href="qhulllib.c#qhull">qh_qhull</a> construct the convex hull of a set of points </li> </ul> @@ -206,7 +210,7 @@ return vertices (if any) for all points</li> print all statistics </li> <li><a href="io.c#printneighborhood">qh_printneighborhood</a> print neighborhood of one or two facets </li> -<li><a href="qhull.c#printsummary">qh_printsummary</a> +<li><a href="qhulllib.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> @@ -227,7 +231,7 @@ 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="qhull.c#errexit2">qh_errexit2</a> report +<li><a href="qhulllib.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> @@ -250,7 +254,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-set.htm b/src/qh-set.htm index 4a7dc21..c8ce814 100644 --- a/src/qh-set.htm +++ b/src/qh-set.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -60,7 +60,7 @@ If a set is full, appending an element copies the set to a larger array. </p> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> • @@ -94,7 +94,7 @@ constants</a></h3> of a set element in bytes </li> <li><a href="qset.h#setT">setT</a> a set with a maximum size and a current size</li> -<li><a href="qhull.h#qh-set">qh global sets</a> +<li><a href="qhulllib.h#qh-set">qh global sets</a> global sets for temporary sets, etc. </li> </ul> <h3><a href="qh-set.htm#TOC">»</a><a name="seach">FOREACH macros</a></h3> @@ -283,7 +283,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-stat.htm b/src/qh-stat.htm index 0b7858d..7e124e5 100644 --- a/src/qh-stat.htm +++ b/src/qh-stat.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -41,7 +41,7 @@ Statistics may be turned off in user.h. If so, all but the 'zz' statistics are ignored.</p> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> @@ -140,7 +140,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qh-user.htm b/src/qh-user.htm index cde5ae0..c7ecd9f 100644 --- a/src/qh-user.htm +++ b/src/qh-user.htm @@ -20,7 +20,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> • <a href="qh-mem.htm">Mem</a> @@ -35,7 +35,7 @@ href="http://www.qhull.org">Home page</a> for Qhull<br> user may want to change. </p> </blockquote> -<p><b>Copyright © 1995-2003 The Geometry Center, Minneapolis MN</b></p> +<p><b>Copyright © 1995-2009 The Geometry Center, Minneapolis MN</b></p> <hr> <p><a href="#TOP">»</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">•</a> <a href="qh-globa.htm#TOC">Global</a> @@ -44,9 +44,10 @@ user may want to change. </p> • <a href="qh-qhull.htm#TOC">Qhull</a> • <a href="qh-set.htm#TOC">Set</a> • <a href="qh-stat.htm#TOC">Stat</a> • <b>User</b> </p> -<h3>Index to <a href="user.c">user.c</a> and +<h3>Index to <a href="user.c">user.c</a>, <a href="user2.c">user2.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> @@ -55,7 +56,17 @@ configuration macros</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">user2.c functions</a> </li> </ul> + +<h3><a href="qh-user.htm#TOC">»</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">»</a><a name="utype">user.h data types and configuration macros</a></h3> <ul> @@ -198,6 +209,18 @@ of points</li> print all fields of all facets </li> </ul> +<h3><a href="qh-user.htm#TOC">»</a><a name="u2func">user2.c +functions</a></h3> +<ul> +<li><a href="user2.c#qh_exit">qh_exit</a> exit program, same as exit().</li> +<li><a href="user2.c#qh_fprintf">qh_fprintf</a> print +information from Qhull, sames as fprintf(). </li> +<li><a href="user2.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print +information from Rbox, sames as fprintf(). </li> +<li><a href="user2.c#qh_free">qh_free</a> free memory, same as free().</li> +<li><a href="user.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li> +</ul> + <p><!-- Navigation links --> </p> <hr> <p><b>Up:</b> @@ -213,7 +236,7 @@ Qhull</a> <br> • <a href="../html/qh-optq.htm#qhull">Qhull</a> • <a href="../html/qh-optc.htm#prec">Precision</a> • <a href="../html/qh-optt.htm#trace">Trace</a><br> -<b>Up:</b> <a href="../html/qh-in.htm#TOC">Qhull internals: Table of Contents</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> • <a href="qh-globa.htm">Global</a> • <a href="qh-io.htm">Io</a> diff --git a/src/qhalf.c b/src/qhalf.c index 0996c54..cf36026 100644 --- a/src/qhalf.c +++ b/src/qhalf.c @@ -6,7 +6,7 @@ see unix.c for full interface - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2008, The Geometry Center */ #include <stdio.h> @@ -14,7 +14,7 @@ #include <string.h> #include <ctype.h> #include <math.h> -#include "qhull.h" +#include "qhulllib.h" #include "mem.h" #include "qset.h" @@ -26,7 +26,7 @@ #elif __cplusplus extern "C" { - int isatty (int); + int isatty(int); } #elif _MSC_VER @@ -34,7 +34,7 @@ extern "C" { #define isatty _isatty #else -int isatty (int); /* returns 1 if stdin is a tty +int isatty(int); /* returns 1 if stdin is a tty if "Undefined symbol" this can be deleted along with call in main() */ #endif @@ -45,7 +45,7 @@ int isatty (int); /* returns 1 if stdin is a tty long prompt for qhull notes: - restricted version of qhull.c + restricted version of qhulllib.c see: concise prompt below @@ -264,10 +264,10 @@ int main(int argc, char *argv[]) { 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"); + 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 @@ -284,25 +284,25 @@ int main(int argc, char *argv[]) { 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(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_option("Halfspace", NULL, NULL); qh HALFspace= True; /* 'H' */ - qh_checkflags (qh qhull_command, hidden_options); - qh_initflags (qh qhull_command); + 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); + points= qh_readpoints(&numpoints, &dim, &ismalloc); if (dim >= 5) { - qh_option ("Qxact_merge", NULL, NULL); + qh_option("Qxact_merge", NULL, NULL); qh MERGEexact= True; /* 'Qx' always */ } - qh_init_B (points, numpoints, dim, ismalloc); + qh_init_B(points, numpoints, dim, ismalloc); qh_qhull(); qh_check_output(); qh_produce_output(); @@ -315,9 +315,9 @@ qhull error: options 'Qbk:n' and 'QBk:n' are not used with qhalf.\n\ qh_freeqhull( True); #else qh_freeqhull( False); - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) - fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", + fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); #endif return exitcode; diff --git a/src/qhull.h b/src/qhull.h index 657f5e4..a57bbe1 100644 --- a/src/qhull.h +++ b/src/qhull.h @@ -2,1029 +2,17 @@ >-------------------------------</a><a name="TOP">-</a> qhull.h - user-level header file for using qhull.a library - see qh-qhull.htm, qhull_a.h + Proxy for qhulllib.h for backwards compatability - copyright (c) 1993-2003, The Geometry Center - - NOTE: access to qh_qh is via the 'qh' macro. This allows - qh_qh to be either a pointer or a structure. An example - of using qh is "qh DROPdim" which accesses the DROPdim - field of qh_qh. Similarly, access to qh_qhstat is via - the 'qhstat' macro. - - includes function prototypes for qhull.c, geom.c, global.c, io.c, user.c - - use mem.h for mem.c - use qset.h for qset.c - - see unix.c for an example of using qhull.h - - recompile qhull if you change this file + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/qhull.h#48 $$Change: 1087 $ + $DateTime: 2009/11/22 23:02:55 $$Author: bbarber $ */ #ifndef qhDEFqhull #define qhDEFqhull 1 -/*=========================== -included files ==============*/ - -#include <setjmp.h> -#include <float.h> -#include <time.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 qhull.h -#endif -#endif -#endif - -#include "user.h" /* user defineable constants */ - -/*============ constants and basic types ====================*/ - -extern 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: - 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 DIM3 coordinates -*/ -#define pointT coordT - -/*-<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 -*/ -#define boolT unsigned int -#ifdef False -#undef False -#endif -#ifdef True -#undef True -#endif -#define False 0 -#define 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 qh names. The similar names are only - used in switch statements in qh_printbegin() etc. -*/ -typedef enum {qh_PRINTnone= 0, - qh_PRINTarea, qh_PRINTaverage, /* 'Fa' 'FV' 'Fc' 'FC' */ - qh_PRINTcoplanars, qh_PRINTcentrums, - qh_PRINTfacets, qh_PRINTfacets_xridge, /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */ - qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, - qh_PRINTnormals, qh_PRINTouter, 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 -*/ -#define qh_ERRnone 0 /* no error occurred during qhull */ -#define qh_ERRinput 1 /* input inconsistency */ -#define qh_ERRsingular 2 /* singular input data */ -#define qh_ERRprec 3 /* precision error */ -#define qh_ERRmem 4 /* insufficient memory, matches mem.h */ -#define qh_ERRqhull 5 /* internal error detected, matches mem.h */ - -/* ============ -structures- ==================== - each of the following structures is defined by a typedef - all realT and coordT fields occur at the beginning of a structure - (otherwise space may be wasted due to alignment) - define all flags together and pack into 32-bit number -*/ - -typedef struct vertexT vertexT; -typedef struct ridgeT ridgeT; -typedef struct facetT facetT; -#ifndef DEFsetT -#define DEFsetT 1 -typedef struct setT setT; /* defined in qset.h */ -#endif - -/*-<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 defines ridge */ - setT *neighbors; /* neighbors of the facet. If simplicial, the kth - neighbor is opposite the kth vertex, and the first - neighbor is the horizon facet for the first vertex*/ - setT *outsideset; /* set of points outside this facet - if non-empty, last point is furthest - if NARROWhull, includes coplanars for partitioning*/ - setT *coplanarset; /* set of points coplanar with this facet - > qh.min_vertex and <= facet->max_outside - a point is assigned to the furthest facet - if non-empty, last point is furthest away */ - unsigned visitid; /* visit_id, for visiting all neighbors, - all uses are independent */ - unsigned id; /* unique identifier from qh facet_id */ - unsigned nummerge:9; /* number of merges */ -#define qh_MAXnummerge 511 /* 2^9-1, 32 flags total, see "flags:" in io.c */ - flagT tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */ - /* all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */ - /* all tricoplanars share the same apex */ - /* if ->degenerate, does not span facet (one logical ridge) */ - /* one tricoplanar has ->keepcentrum and ->coplanarset */ - /* during qh_triangulate, f.trivisible points to original facet */ - flagT newfacet:1; /* True if facet on qh newfacet_list (new or merged) */ - flagT visible:1; /* True if visible facet (will be deleted) */ - flagT toporient:1; /* True if created with top orientation - after merging, use ridge orientation */ - flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */ - flagT seen:1; /* used to perform operations only once, like visitid */ - flagT seen2:1; /* used to perform operations only once, like visitid */ - flagT flipped:1; /* True if facet is flipped */ - flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */ - flagT notfurthest:1; /* True if last point of outsideset is not furthest*/ - -/*-------- flags primarily for output ---------*/ - flagT good:1; /* True if a facet marked good for output */ - flagT isarea:1; /* True if facet->f.area is defined */ - -/*-------- flags for merging ------------------*/ - flagT dupridge:1; /* True if duplicate ridge in facet */ - flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge - ->normal defined (also defined for mergeridge2) */ - flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */ - flagT coplanar:1; /* True if horizon facet is coplanar at last use */ - flagT mergehorizon:1; /* True if will merge into horizon (->coplanar) */ - flagT cycledone:1;/* True if mergecycle_all already done */ - flagT tested:1; /* True if facet convexity has been tested (false after merge */ - flagT keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */ - flagT newmerge:1; /* True if facet is newly merged for reducevertices */ - flagT degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */ - flagT redundant:1; /* True if facet is redundant (degen_mergeset) */ -}; - - -/*-<a href="qh-poly.htm#TOC" - >--------------------------------</a><a name="ridgeT">-</a> - - ridgeT - defines a ridge - - notes: - a ridge is DIM3-1 simplex between two neighboring facets. If the - facets are non-simplicial, there may be more than one ridge between - two facets. E.G. a 4-d hypercube has two triangles between each pair - of neighboring facets. - - topological information: - vertices a set of vertices - top,bottom neighboring facets with orientation - - geometric information: - tested True if ridge is clearly convex - nonconvex True if ridge is non-convex -*/ -struct ridgeT { - setT *vertices; /* vertices belonging to this ridge, inverse sorted by ID - NULL if a degen ridge (matchsame) */ - facetT *top; /* top facet this ridge is part of */ - facetT *bottom; /* bottom facet this ridge is part of */ - unsigned id:24; /* unique identifier, =>room for 8 flags */ - flagT seen:1; /* used to perform operations only once */ - flagT tested:1; /* True when ridge is tested for convexity */ - flagT nonconvex:1; /* True if getmergeset detected a non-convex neighbor - only one ridge between neighbors may have nonconvex */ -}; - -/*-<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; /* for use with qh vertex_visit */ - unsigned id:24; /* unique identifier, =>room for 8 flags */ - flagT seen:1; /* used to perform operations only once */ - flagT seen2:1; /* another seen flag */ - flagT delridge:1; /* vertex was part of a deleted ridge */ - flagT deleted:1; /* true if vertex on qh del_vertices */ - flagT newlist:1; /* true if vertex on qh newvertex_list */ -}; - -/*======= -global variables -qh ============================*/ - -/*-<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 and qhstat is defined in stat.h - Access to qh_qh is via the "qh" macro. See qh_QHpointer in user.h -*/ -typedef struct qhT qhT; -#if qh_QHpointer -#define qh qh_qh-> -extern qhT *qh_qh; /* allocated in global.c */ -#else -#define qh qh_qh. -extern qhT qh_qh; -#endif - -struct qhT { - -/*-<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 ATinfinity; /* true 'Qz' if point num_points-1 is "at-infinity" - for improving precision in Delaunay triangulations */ - boolT AVOIDold; /* true 'Q4' if avoid old->new merges */ - boolT BESToutside; /* true 'Qf' if partition points into best outsideset */ - boolT CDDinput; /* true 'Pc' if input uses CDD format (1.0/offset first) */ - boolT CDDoutput; /* true 'PC' if print normals in CDD format (offset first) */ - boolT CHECKfrequently; /* true 'Tc' if checking frequently */ - realT premerge_cos; /* 'A-n' cos_max when pre merging */ - realT postmerge_cos; /* 'An' cos_max when post merging */ - boolT DELAUNAY; /* true 'd' if computing DELAUNAY triangulation */ - boolT DOintersections; /* true 'Gh' if print hyperplane intersections */ - int DROPdim; /* drops dim 'GDn' for 4-d -> 3-d output */ - boolT FORCEoutput; /* true 'Po' if forcing output despite degeneracies */ - int GOODpoint; /* 1+n for 'QGn', good facet if visible/not(-) from point n*/ - pointT *GOODpointp; /* the actual point */ - boolT GOODthreshold; /* true if qh lower_threshold/upper_threshold defined - false if qh SPLITthreshold */ - int GOODvertex; /* 1+n, good facet if vertex for point n */ - pointT *GOODvertexp; /* the actual point */ - boolT HALFspace; /* true 'Hn,n,n' if halfspace intersection */ - int IStracing; /* trace execution, 0=none, 1=least, 4=most, -1=events */ - int KEEParea; /* 'PAn' number of largest facets to keep */ - boolT KEEPcoplanar; /* true 'Qc' if keeping nearest facet for coplanar points */ - boolT KEEPinside; /* true 'Qi' if keeping nearest facet for inside points - set automatically if 'd Qc' */ - int KEEPmerge; /* 'PMn' number of facets to keep with most merges */ - realT KEEPminArea; /* 'PFn' minimum facet area to keep */ - realT MAXcoplanar; /* 'Un' max distance below a facet to be coplanar*/ - boolT MERGEexact; /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */ - boolT MERGEindependent; /* true 'Q2' if merging independent sets */ - boolT MERGING; /* true if exact-, pre- or post-merging, with angle and centrum tests */ - realT premerge_centrum; /* 'C-n' centrum_radius when pre merging. Default is round-off */ - realT postmerge_centrum; /* 'Cn' centrum_radius when post merging. Default is round-off */ - boolT MERGEvertices; /* true 'Q3' if merging redundant vertices */ - realT MINvisible; /* 'Vn' min. distance for a facet to be visible */ - boolT NOnarrow; /* true 'Q10' if no special processing for narrow distributions */ - boolT NOnearinside; /* true 'Q8' if ignore near-inside points when partitioning */ - boolT NOpremerge; /* true 'Q0' if no defaults for C-0 or Qx */ - boolT ONLYgood; /* true 'Qg' if process points with good visible or horizon facets */ - boolT ONLYmax; /* true 'Qm' if only process points that increase max_outside */ - boolT PICKfurthest; /* true 'Q9' if process furthest of furthest points*/ - boolT POSTmerge; /* true if merging after buildhull (Cn or An) */ - boolT PREmerge; /* true if merging during buildhull (C-n or A-n) */ - /* NOTE: some of these names are similar to qh_PRINT names */ - boolT PRINTcentrums; /* true 'Gc' if printing centrums */ - boolT PRINTcoplanar; /* true 'Gp' if printing coplanar points */ - int PRINTdim; /* print dimension for Geomview output */ - boolT PRINTdots; /* true 'Ga' if printing all points as dots */ - boolT PRINTgood; /* true 'Pg' if printing good facets */ - boolT PRINTinner; /* true 'Gi' if printing inner planes */ - boolT PRINTneighbors; /* true 'PG' if printing neighbors of good facets */ - boolT PRINTnoplanes; /* true 'Gn' if printing no planes */ - boolT PRINToptions1st; /* true 'FO' if printing options to stderr */ - boolT PRINTouter; /* true 'Go' if printing outer planes */ - boolT PRINTprecision; /* false 'Pp' if not reporting precision problems */ - qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */ - boolT PRINTridges; /* true 'Gr' if print ridges */ - boolT PRINTspheres; /* true 'Gv' if print vertices as spheres */ - boolT PRINTstatistics; /* true 'Ts' if printing statistics to stderr */ - boolT PRINTsummary; /* true 's' if printing summary to stderr */ - boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */ - boolT PROJECTdelaunay; /* true if DELAUNAY, no readpoints() and - need projectinput() for Delaunay in qh_init_B */ - int PROJECTinput; /* number of projected dimensions 'bn:0Bn:0' */ - boolT QUICKhelp; /* true if quick help message for degen input */ - boolT RANDOMdist; /* true if randomly change distplane and setfacetplane */ - realT RANDOMfactor; /* maximum random perturbation */ - realT RANDOMa; /* qh_randomfactor is randr * RANDOMa + RANDOMb */ - realT RANDOMb; - boolT RANDOMoutside; /* true if select a random outside point */ - int REPORTfreq; /* buildtracing reports every n facets */ - int REPORTfreq2; /* tracemerging reports every REPORTfreq/2 facets */ - int RERUN; /* 'TRn' rerun qhull n times (qh.build_cnt) */ - int ROTATErandom; /* 'QRn' seed, 0 time, >= rotate input */ - boolT SCALEinput; /* true 'Qbk' if scaling input */ - boolT SCALElast; /* true 'Qbb' if scale last coord to max prev coord */ - boolT SETroundoff; /* true 'E' if qh DISTround is predefined */ - boolT SKIPcheckmax; /* true 'Q5' if skip qh_check_maxout */ - boolT SKIPconvex; /* true 'Q6' if skip convexity testing during pre-merge */ - boolT SPLITthresholds; /* true if upper_/lower_threshold defines a region - used only for printing (not for qh ONLYgood) */ - int STOPcone; /* 'TCn' 1+n for stopping after cone for point n*/ - /* also used by qh_build_withresart for err exit*/ - int STOPpoint; /* 'TVn' 'TV-n' 1+n for stopping after/before(-) - adding point n */ - int TESTpoints; /* 'QTn' num of test points after qh.num_points. Test points always coplanar. */ - boolT TESTvneighbors; /* true 'Qv' if test vertex neighbors at end */ - int TRACElevel; /* 'Tn' conditional IStracing level */ - int TRACElastrun; /* qh.TRACElevel applies to last qh.RERUN */ - int TRACEpoint; /* 'TPn' start tracing when point n is a vertex */ - realT TRACEdist; /* 'TWn' start tracing when merge distance too big */ - int TRACEmerge; /* 'TMn' start tracing before this merge */ - boolT TRIangulate; /* true 'Qt' if triangulate non-simplicial facets */ - boolT TRInormals; /* true 'Q11' if triangulate duplicates normals (sets Qt) */ - boolT UPPERdelaunay; /* true 'Qu' if computing furthest-site Delaunay */ - boolT VERIFYoutput; /* true 'Tv' if verify output at end of qhull */ - boolT VIRTUALmemory; /* true 'Q7' if depth-first processing in buildhull */ - boolT VORONOI; /* true 'v' if computing Voronoi diagram */ - - /*--------input constants ---------*/ - realT AREAfactor; /* 1/(hull_dim-1)! for converting det's to area */ - boolT DOcheckmax; /* true if calling qh_check_maxout (qh_initqhull_globals) */ - char *feasible_string; /* feasible point 'Hn,n,n' for halfspace intersection */ - coordT *feasible_point; /* as coordinates, both malloc'd */ - boolT GETarea; /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io.c */ - boolT KEEPnearinside; /* true if near-inside points in coplanarset */ - int hull_dim; /* dimension of hull, set by initbuffers */ - int input_dim; /* dimension of input, set by initbuffers */ - int num_points; /* number of input points */ - pointT *first_point; /* array of input points, see POINTSmalloc */ - boolT POINTSmalloc; /* true if qh first_point/num_points allocated */ - pointT *input_points; /* copy of original qh.first_point for input points for qh_joggleinput */ - boolT input_malloc; /* true if qh input_points malloc'd */ - char qhull_command[256];/* command line that invoked this program */ - char rbox_command[256]; /* command line that produced the input points */ - char qhull_options[512];/* descriptive list of options */ - int qhull_optionlen; /* length of last line */ - int qhull_optionsiz; /* size of qhull_options before qh_initbuild */ - boolT VERTEXneighbors; /* true if maintaining vertex neighbors */ - boolT ZEROcentrum; /* true if 'C-0' or 'C-0 Qx'. sets ZEROall_ok */ - realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k] - must set either GOODthreshold or SPLITthreshold - if Delaunay, default is 0.0 for upper envelope */ - realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */ - realT *upper_bound; /* scale point[k] to new upper bound */ - realT *lower_bound; /* scale point[k] to new lower bound - project if both upper_ and lower_bound == 0 */ - -/*-<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 */ - 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-intern">-</a> - - qh internal constants - internal constants for Qhull -*/ - char qhull[sizeof("qhull")]; /* for checking ownership */ - void *old_stat; /* pointer to saved qh_qhstat, qh_save_qhull */ - jmp_buf errexit; /* exit label for qh_errexit, defined by setjmp() */ - char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */ - jmp_buf restartexit; /* restart label for qh_errexit, defined by setjmp() */ - char jmpXtra2[40]; /* extra bytes in case jmp_buf is defined wrong by compiler*/ - FILE *fin; /* pointer to input file, init by qh_meminit */ - FILE *fout; /* pointer to output file */ - FILE *ferr; /* pointer to error file */ - pointT *interior_point; /* center point of the initial simplex*/ - int normal_size; /* size in bytes for facet normals and point coords*/ - int center_size; /* size in bytes for Voronoi centers */ - int TEMPsize; /* size for small, temporary sets (in quick mem) */ - -/*-<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; /* 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 */ - realT JOGGLEmax; /* set 'QJn' if randomly joggle input */ - boolT maxoutdone; /* set qh_check_maxout(), cleared by qh_addpoint() */ - realT max_outside; /* maximum distance from a point to a facet, - before roundoff, not simplicial vertices - actual outer plane is +DISTround and - computed outer plane is +2*DISTround */ - realT max_vertex; /* maximum distance (>0) from vertex to a facet, - before roundoff, due to a merge */ - realT min_vertex; /* minimum distance (<0) from vertex to a facet, - before roundoff, due to a merge - if qh.JOGGLEmax, qh_makenewplanes sets it - recomputed if qh.DOcheckmax, default -qh.DISTround */ - boolT NEWfacets; /* true while visible facets invalid due to new or merge - from makecone/attachnewfacets to deletevisible */ - boolT findbestnew; /* true if partitioning calls qh_findbestnew */ - boolT findbest_notsharp; /* true if new facets are at least 90 degrees */ - boolT NOerrexit; /* true if qh.errexit is not available */ - realT PRINTcradius; /* radius for printing centrums */ - realT PRINTradius; /* radius for printing vertex spheres and points */ - boolT POSTmerging; /* true when post merging */ - int printoutvar; /* temporary variable for qh_printbegin, etc. */ - int printoutnum; /* number of facets printed */ - boolT QHULLfinished; /* True after qhull() is finished */ - realT totarea; /* 'FA': total facet area computed by qh_getarea */ - realT totvol; /* 'FA': total volume computed by qh_getarea */ - unsigned int visit_id; /* unique ID for searching neighborhoods, */ - unsigned int vertex_visit; /* unique ID for searching vertices */ - boolT ZEROall_ok; /* True if qh_checkzero always succeeds */ - boolT WAScoplanar; /* True if qh_partitioncoplanar (qh_check_maxout) */ - -/*-<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 (first is qh interior_point) */ - 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 errexit (prevents duplicate calls */ - boolT firstcentrum; /* for qh_printcentrum */ - realT last_low; /* qh_scalelast parameters for qh_setdelaunay */ - realT last_high; - realT last_newhigh; - unsigned lastreport; /* for qh_buildtracing */ - int mergereport; /* for qh_tracemerging */ - boolT old_randomdist; /* save RANDOMdist when io, tracing, or statistics */ - int ridgeoutnum; /* number of ridges in 4OFF output */ - void *old_qhstat; /* for saving qh_qhstat in save_qhull() */ - setT *old_tempstack; /* for saving qhmem.tempstack in save_qhull */ - setT *coplanarset; /* set of coplanar facets for searching qh_findbesthorizon() */ -}; - -/*=========== -macros- =========================*/ - -/*-<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 ID for facet, ridge, or vertex - return MAXINT if NULL (-1 causes type conversion error ) -*/ -#define getid_(p) ((p) ? (p)->id : -1) - -/*============== 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) - -/********* -qhull.c prototypes (duplicated from qhull_a.h) **********************/ - -void qh_qhull (void); -boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist); -void qh_printsummary(FILE *fp); - -/********* -user.c prototypes (alphabetical) **********************/ - -void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge); -void qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex); -int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, - char *qhull_cmd, FILE *outfile, FILE *errfile); -void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall); -void qh_user_memsizes (void); - -/***** -geom.c/geom2.c prototypes (duplicated from geom.h) ****************/ - -facetT *qh_findbest (pointT *point, facetT *startfacet, - boolT bestoutside, boolT newfacets, boolT noupper, - realT *dist, boolT *isoutside, int *numpart); -facetT *qh_findbestnew (pointT *point, facetT *startfacet, - realT *dist, boolT bestoutside, boolT *isoutside, int *numpart); -boolT qh_gram_schmidt(int dim, realT **rows); -void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane); -void qh_printsummary(FILE *fp); -void qh_projectinput (void); -void qh_randommatrix (realT *buffer, int dim, realT **row); -void qh_rotateinput (realT **rows); -void qh_scaleinput (void); -void qh_setdelaunay (int dim, int count, pointT *points); -coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible); - -/***** -global.c prototypes (alphabetical) ***********************/ - -unsigned long qh_clock (void); -void qh_checkflags (char *command, char *hiddenflags); -void qh_freebuffers (void); -void qh_freeqhull (boolT allmem); -void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]); -void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc); -void qh_init_qhull_command (int argc, char *argv[]); -void qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc); -void qh_initflags (char *command); -void qh_initqhull_buffers (void); -void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc); -void qh_initqhull_mem (void); -void qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile); -void qh_initthresholds (char *command); -void qh_option (char *option, int *i, realT *r); -#if qh_QHpointer -void qh_restore_qhull (qhT **oldqh); -qhT *qh_save_qhull (void); -#endif - -/***** -io.c prototypes (duplicated from io.h) ***********************/ - -void dfacet( unsigned id); -void dvertex( unsigned id); -void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall); -void qh_produce_output(void); -coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc); - - -/********* -mem.c prototypes (duplicated from mem.h) **********************/ - -void qh_meminit (FILE *ferr); -void qh_memfreeshort (int *curlong, int *totlong); - -/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/ - -void qh_check_output (void); -void qh_check_points (void); -setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets); -facetT *qh_findbestfacet (pointT *point, boolT bestoutside, - realT *bestdist, boolT *isoutside); -vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp); -pointT *qh_point (int id); -setT *qh_pointfacet (void /*qh.facet_list*/); -int qh_pointid (pointT *point); -setT *qh_pointvertex (void /*qh.facet_list*/); -void qh_setvoronoi_all (void); -void qh_triangulate (void /*qh facet_list*/); - -/********* -stat.c prototypes (duplicated from stat.h) **********************/ - -void qh_collectstatistics (void); -void qh_printallstatistics (FILE *fp, char *string); +#include "qhulllib.h #endif /* qhDEFqhull */ diff --git a/src/qhull_a.h b/src/qhull_a.h index 027cafa..f5842a2 100644 --- a/src/qhull_a.h +++ b/src/qhull_a.h @@ -1,18 +1,20 @@ /*<html><pre> -<a href="qh-qhull.htm" >-------------------------------</a><a name="TOP">-</a> - qhull_a.h + qhull_a.h all header files for compiling qhull see qh-qhull.htm - see qhull.h for user-level definitions - + see qhulllib.h for user-level definitions + see user.h for user-defineable constants - - defines internal functions for qhull.c global.c - copyright (c) 1993-2003, The Geometry Center + defines internal functions for qhulllib.c global.c + + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/qhull_a.h#22 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ Notes: grep for ((" and (" to catch fprintf("lkasdjf"); full parens around (x?y:z) @@ -20,10 +22,19 @@ */ #ifndef qhDEFqhulla -#define qhDEFqhulla +#define qhDEFqhulla 1 + +#include "qhulllib.h" /* Defines data types */ + +#include "stat.h" +#include "random.h" +#include "mem.h" +#include "qset.h" +#include "geom.h" +#include "merge.h" +#include "poly.h" +#include "io.h" -#include <stdio.h> -#include <stdlib.h> #include <setjmp.h> #include <string.h> #include <math.h> @@ -31,50 +42,44 @@ #include <limits.h> #include <time.h> #include <ctype.h> +#include <stdio.h> +#include <stdlib.h> /*** uncomment here and qset.c if string.h does not define memcpy() #include <memory.h> */ -#include "qhull.h" -#include "mem.h" -#include "qset.h" -#include "geom.h" -#include "merge.h" -#include "poly.h" -#include "io.h" -#include "stat.h" -#if qh_CLOCKtype == 2 /* defined in user.h from qhull.h */ +#if qh_CLOCKtype == 2 /* defined in user.h from qhulllib.h */ #include <sys/types.h> #include <sys/times.h> #include <unistd.h> #endif -#ifdef _MSC_VER /* Microsoft Visual C++ */ -#pragma warning( disable : 4056) /* float constant expression. Looks like a compiler bug */ -#pragma warning( disable : 4146) /* unary minus applied to unsigned type */ -#pragma warning( disable : 4244) /* conversion from 'unsigned long' to 'real' */ -#pragma warning( disable : 4305) /* conversion from 'const double' to 'float' */ +#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((fp.ferr, "format\n", vars)); - calls fprintf if qh.IStracing >= N - + + traceN((qh ferr, 0Nnnn, "format\n", vars)); + calls qh_fprintf if qh.IStracing >= N + notes: removing tracing reduces code size but doesn't change execution speed */ #ifndef qh_NOtrace -#define trace0(args) {if (qh IStracing) fprintf args;} -#define trace1(args) {if (qh IStracing >= 1) fprintf args;} -#define trace2(args) {if (qh IStracing >= 2) fprintf args;} -#define trace3(args) {if (qh IStracing >= 3) fprintf args;} -#define trace4(args) {if (qh IStracing >= 4) fprintf args;} -#define trace5(args) {if (qh IStracing >= 5) fprintf args;} +#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) {} @@ -84,44 +89,42 @@ #define trace5(args) {} #endif /* qh_NOtrace */ -/***** -qhull.c prototypes (alphabetical after qhull) ********************/ +/***** -qhulllib.c prototypes (alphabetical after qhull) ********************/ -void qh_qhull (void); -boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist); +void qh_qhull(void); +boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist); void qh_buildhull(void); -void qh_buildtracing (pointT *furthest, facetT *facet); -void qh_build_withrestart (void); +void qh_buildtracing(pointT *furthest, facetT *facet); +void qh_build_withrestart(void); void qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet); void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon); -pointT *qh_nextfurthest (facetT **visible); +pointT *qh_nextfurthest(facetT **visible); void qh_partitionall(setT *vertices, pointT *points,int npoints); -void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist); -void qh_partitionpoint (pointT *point, facetT *facet); +void qh_partitioncoplanar(pointT *point, facetT *facet, realT *dist); +void qh_partitionpoint(pointT *point, facetT *facet); void qh_partitionvisible(boolT allpoints, int *numpoints); -void qh_precision (char *reason); +void qh_precision(char *reason); void qh_printsummary(FILE *fp); /***** -global.c internal prototypes (alphabetical) ***********************/ -void qh_appendprint (qh_PRINT format); -void qh_freebuild (boolT allmem); -void qh_freebuffers (void); -void qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc); -int qh_strtol (const char *s, char **endp); -double qh_strtod (const char *s, char **endp); +void qh_appendprint(qh_PRINT format); +void qh_freebuild(boolT allmem); +void qh_freebuffers(void); +void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc); /***** -stat.c internal prototypes (alphabetical) ***********************/ -void qh_allstatA (void); -void qh_allstatB (void); -void qh_allstatC (void); -void qh_allstatD (void); -void qh_allstatE (void); +void qh_allstatA(void); +void qh_allstatB(void); +void qh_allstatC(void); +void qh_allstatD(void); +void qh_allstatE(void); void qh_allstatE2 (void); -void qh_allstatF (void); -void qh_allstatG (void); -void qh_allstatH (void); -void qh_freebuffers (void); -void qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc); +void qh_allstatF(void); +void qh_allstatG(void); +void qh_allstatH(void); +void qh_freebuffers(void); +void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc); #endif /* qhDEFqhulla */ diff --git a/src/qhull.c b/src/qhulllib.c similarity index 70% rename from src/qhull.c rename to src/qhulllib.c index 55a1521..76563b2 100644 --- a/src/qhull.c +++ b/src/qhulllib.c @@ -1,16 +1,18 @@ /*<html><pre> -<a href="qh-qhull.htm" >-------------------------------</a><a name="TOP">-</a> - qhull.c + qhulllib.c Quickhull algorithm for convex hulls qhull() and top-level routines - see qh-qhull.htm, qhull.h, unix.c + see qh-qhull.htm, qhulllib.h, unix.c see qhull_a.h for internal functions - copyright (c) 1993-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/qhulllib.c#3 $$Change: 1095 $ + $DateTime: 2009/12/01 22:40:56 $$Author: bbarber $ */ #include "qhull_a.h" @@ -55,7 +57,7 @@ record end time */ -void qh_qhull (void) { +void qh_qhull(void) { int numoutside; qh hulltime= qh_CPUclock; @@ -69,44 +71,44 @@ void qh_qhull (void) { if (qh ZEROall_ok && !qh TESTvneighbors && qh MERGEexact) qh_checkzero( qh_ALL); if (qh ZEROall_ok && !qh TESTvneighbors && !qh WAScoplanar) { - trace2((qh ferr, "qh_qhull: all facets are clearly convex and no coplanar points. Post-merging and check of maxout not needed.\n")); + 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("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_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("For post-merging", qh postmerge_centrum, qh postmerge_cos, qh TESTvneighbors); if (qh visible_list == qh facet_list) { /* i.e., merging done */ qh findbestnew= True; - qh_partitionvisible (/*visible_list, newfacet_list*/ !qh_ALL, &numoutside); + qh_partitionvisible(/*visible_list, newfacet_list*/ !qh_ALL, &numoutside); qh findbestnew= False; - qh_deletevisible (/*qh visible_list*/); - qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */); + qh_deletevisible(/*qh visible_list*/); + qh_resetlists(False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */); } } if (qh DOcheckmax){ if (qh REPORTfreq) { - qh_buildtracing (NULL, NULL); - fprintf (qh ferr, "\nTesting all coplanar points.\n"); + qh_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 ((setT*)qhmem.tempstack) != 0) { - fprintf (qh ferr, "qhull internal error (qh_qhull): temporary sets not empty (%d)\n", - qh_setsize ((setT*)qhmem.tempstack)); - qh_errexit (qh_ERRqhull, NULL, NULL); + if (qh_setsize((setT*)qhmem.tempstack) != 0) { + qh_fprintf(qh ferr, 6164, "qhull internal error (qh_qhull): temporary sets not empty(%d)\n", + qh_setsize((setT*)qhmem.tempstack)); + qh_errexit(qh_ERRqhull, NULL, NULL); } qh hulltime= qh_CPUclock - qh hulltime; qh QHULLfinished= True; - trace1((qh ferr, "qh_qhull: algorithm completed\n")); + trace1((qh ferr, 1036, "qh_qhull: algorithm completed\n")); } /* qhull */ /*-<a href="qh-qhull.htm#TOC" @@ -141,7 +143,7 @@ void qh_qhull (void) { qh_triangulate() -- triangulate non-simplicial facets design: - check point in qh.first_point/.num_points + add point to other_points if needed if checkdist if point not above facet partition coplanar point @@ -163,7 +165,7 @@ void qh_qhull (void) { exit if post STOPpoint requested reset working lists of facets and vertices */ -boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) { +boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist) { int goodvisible, goodhorizon; vertexT *vertex; facetT *newfacet; @@ -172,52 +174,52 @@ boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) { int numpart, numpoints, numnew, firstnew; qh maxoutdone= False; - if (qh_pointid (furthest) == -1) - qh_setappend (&qh other_points, furthest); + if (qh_pointid(furthest) == -1) + qh_setappend(&qh other_points, furthest); if (!facet) { - fprintf (qh ferr, "qh_addpoint: NULL facet. Need to call qh_findbestfacet first\n"); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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, + 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); + qh_partitioncoplanar(furthest, facet, &dist); return True; } } - qh_buildtracing (furthest, facet); + 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); + 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 */); + 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 */); + 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) { + && !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 */); + 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; @@ -232,7 +234,7 @@ boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) { } qh findbestnew= False; if (qh PREmerge || qh MERGEexact) { - qh_premerge (vertex, qh premerge_centrum, qh premerge_cos); + qh_premerge(vertex, qh premerge_centrum, qh premerge_cos); if (qh_USEfindbestnew) qh findbestnew= True; else { @@ -245,7 +247,7 @@ boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) { } }else if (qh BESToutside) qh findbestnew= True; - qh_partitionvisible (/*visible_list, newfacet_list*/ !qh_ALL, &numpoints); + qh_partitionvisible(/*visible_list, newfacet_list*/ !qh_ALL, &numpoints); qh findbestnew= False; qh findbest_notsharp= False; zinc_(Zpbalance); @@ -253,26 +255,26 @@ boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) { * (qh num_points - qh num_vertices)/qh num_vertices; wadd_(Wpbalance, pbalance); wadd_(Wpbalance2, pbalance * pbalance); - qh_deletevisible (/*qh visible_list*/); + 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); + 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); + qh_checkpolygon(qh facet_list); else - qh_checkpolygon (qh newfacet_list); + 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_resetlists(True, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */); /* qh_triangulate(); to test qh.TRInormals */ - trace2((qh ferr, "qh_addpoint: added p%d new facets %d new balance %2.2g point balance %2.2g\n", - qh_pointid (furthest), numnew, newbalance, pbalance)); + 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 */ @@ -284,39 +286,37 @@ boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) { qh.FIRSTpoint/qh.NUMpoints is point array it may be moved by qh_joggleinput() */ -void qh_build_withrestart (void) { +void qh_build_withrestart(void) { int restart; qh ALLOWrestart= True; while (True) { - restart= setjmp (qh restartexit); /* simple statement for CRAY J916 */ + restart= setjmp(qh restartexit); /* simple statement for CRAY J916 */ if (restart) { /* only from qh_precision() */ zzinc_(Zretry); wmax_(Wretrymax, qh JOGGLEmax); - qh ERREXITcalled= False; qh STOPcone= True; /* if break, prevents normal output */ } if (!qh RERUN && qh JOGGLEmax < REALmax/2) { if (qh build_cnt > qh_JOGGLEmaxretry) { - fprintf(qh ferr, "\n\ + qh_fprintf(qh ferr, 6229, "\n\ qhull precision error: %d attempts to construct a convex hull\n\ with joggled input. Increase joggle above 'QJ%2.2g'\n\ or modify qh_JOGGLE... parameters in user.h\n", qh build_cnt, qh JOGGLEmax); - qh_errexit (qh_ERRqhull, NULL, NULL); + qh_errexit(qh_ERRqhull, NULL, NULL); } if (qh build_cnt && !restart) break; }else if (qh build_cnt && qh build_cnt >= qh RERUN) break; - qh STOPcone= False; - qh_freebuild (True); /* first call is a nop */ + qh_freebuild(True); /* first call is a nop */ qh build_cnt++; if (!qh qhull_optionsiz) - qh qhull_optionsiz= strlen (qh qhull_options); + qh qhull_optionsiz= (int)strlen(qh qhull_options); /* WARN64 */ else { qh qhull_options [qh qhull_optionsiz]= '\0'; - qh qhull_optionlen= 80; + qh qhull_optionlen= qh_OPTIONline; /* starts a new line */ } qh_option("_run", &qh build_cnt, NULL); if (qh build_cnt == qh RERUN) { @@ -332,7 +332,7 @@ qhull precision error: %d attempts to construct a convex hull\n\ qh_initbuild(); qh_buildhull(); if (qh JOGGLEmax < REALmax/2 && !qh MERGING) - qh_checkconvex (qh facet_list, qh_ALGORITHMfault); + qh_checkconvex(qh facet_list, qh_ALGORITHMfault); } qh ALLOWrestart= False; } /* qh_build_withrestart */ @@ -365,42 +365,42 @@ void qh_buildhull(void) { vertexT *vertex; int id; - trace1((qh ferr, "qh_buildhull: start build hull\n")); + trace1((qh ferr, 1037, "qh_buildhull: start build hull\n")); FORALLfacets { if (facet->visible || facet->newfacet) { - fprintf (qh ferr, "qhull internal error (qh_buildhull): visible or new facet f%d in facet list\n", + 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); + qh_errexit(qh_ERRqhull, facet, NULL); } } FORALLvertices { if (vertex->newlist) { - fprintf (qh ferr, "qhull internal error (qh_buildhull): new vertex f%d in vertex list\n", + 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); + qh_errprint("ERRONEOUS", NULL, NULL, NULL, vertex); + qh_errexit(qh_ERRqhull, NULL, NULL); } - id= qh_pointid (vertex->point); + id= qh_pointid(vertex->point); if ((qh STOPpoint>0 && id == qh STOPpoint-1) || (qh STOPpoint<0 && id == -qh STOPpoint-1) || (qh STOPcone>0 && id == qh STOPcone-1)) { - trace1((qh ferr,"qh_buildhull: stop point or cone P%d in initial hull\n", id)); + 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))) { + while ((furthest= qh_nextfurthest(&facet))) { qh num_outside--; /* if ONLYmax, furthest may not be outside */ - if (!qh_addpoint (furthest, facet, qh ONLYmax)) + if (!qh_addpoint(furthest, facet, qh ONLYmax)) break; } if (qh NARROWhull) /* move points from outsideset to coplanarset */ qh_outcoplanar( /* facet_list */ ); if (qh num_outside && !furthest) { - fprintf (qh ferr, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh num_outside); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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, "qh_buildhull: completed the hull construction\n")); + trace1((qh ferr, 1039, "qh_buildhull: completed the hull construction\n")); } /* buildhull */ @@ -430,7 +430,7 @@ void qh_buildhull(void) { 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) { +void qh_buildtracing(pointT *furthest, facetT *facet) { realT dist= 0; float cpu; int total, furthestid; @@ -441,19 +441,19 @@ void qh_buildtracing (pointT *furthest, facetT *facet) { qh old_randomdist= qh RANDOMdist; qh RANDOMdist= False; if (!furthest) { - time (&timedata); - tp= localtime (&timedata); - cpu= qh_CPUclock - qh hulltime; + time(&timedata); + tp= localtime(&timedata); + cpu= (float)qh_CPUclock - qh hulltime; cpu /= qh_SECticks; total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot); - fprintf (qh ferr, "\n\ + 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); + furthestid= qh_pointid(furthest); if (qh TRACEpoint == furthestid) { qh IStracing= qh TRACElevel; qhmem.IStracing= qh TRACElevel; @@ -463,37 +463,41 @@ At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n } if (qh REPORTfreq && (qh facet_id-1 > qh lastreport+qh REPORTfreq)) { qh lastreport= qh facet_id-1; - time (&timedata); - tp= localtime (&timedata); - cpu= qh_CPUclock - qh hulltime; + time(&timedata); + tp= localtime(&timedata); + cpu= (float)qh_CPUclock - qh hulltime; cpu /= qh_SECticks; total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot); zinc_(Zdistio); - qh_distplane (furthest, facet, &dist); - fprintf (qh ferr, "\n\ + 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", + outside points. Next is point p%d(v%d), %2.2g above f%d.\n", tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1, total, qh num_facets, qh num_vertices, qh num_outside+1, furthestid, qh vertex_id, dist, getid_(facet)); }else if (qh IStracing >=1) { - cpu= qh_CPUclock - qh hulltime; + cpu= (float)qh_CPUclock - qh hulltime; cpu /= qh_SECticks; - qh_distplane (furthest, facet, &dist); - fprintf (qh ferr, "qh_addpoint: add p%d (v%d) to hull of %d facets (%2.2g above f%d) and %d outside at %4.4g CPU secs. Previous was p%d.\n", + 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= qh visit_id; + facet->visitid= 0; } - if (qh vertex_visit > (unsigned) INT_MAX) { + zmax_(Zvvisit2max, (int)qh vertex_visit/2); + if (qh vertex_visit > (unsigned) INT_MAX/2) { /* 31 bits */ + zinc_(Zvvisit); qh vertex_visit= 0; FORALLvertices - vertex->visitid= qh vertex_visit; + vertex->visitid= 0; } qh furthest_id= furthestid; qh RANDOMdist= qh old_randomdist; @@ -510,12 +514,12 @@ At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n assumes exitcode non-zero see: - normally use qh_errexit() in user.c (reports a facet and a ridge) + 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); + qh_errexit(exitcode, NULL, NULL); } /* errexit2 */ @@ -552,7 +556,7 @@ void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhor int numhorizon= 0, coplanar= 0; realT dist; - trace1((qh ferr,"qh_findhorizon: find horizon for point p%d facet f%d\n",qh_pointid(point),facet->id)); + 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 */ @@ -564,12 +568,12 @@ void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhor facet->visible= True; facet->f.replace= NULL; if (qh IStracing >=4) - qh_errprint ("visible", facet, NULL, NULL, NULL); + qh_errprint("visible", facet, NULL, NULL, NULL); qh visit_id++; FORALLvisible_facets { if (visible->tricoplanar && !qh TRInormals) { - fprintf (qh ferr, "qh_findhorizon: does not work for tricoplanar facets. Use option 'Q11'\n"); - qh_errexit (qh_ERRqhull, visible, NULL); + 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) { @@ -588,12 +592,12 @@ void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhor if (neighbor->good) (*goodvisible)++; if (qh IStracing >=4) - qh_errprint ("visible", neighbor, NULL, NULL, NULL); + qh_errprint("visible", neighbor, NULL, NULL, NULL); }else { if (dist > - qh MAXcoplanar) { neighbor->coplanar= True; zzinc_(Zcoplanarhorizon); - qh_precision ("coplanar horizon"); + qh_precision("coplanar horizon"); coplanar++; if (qh MERGING) { if (dist > 0) { @@ -605,7 +609,7 @@ void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhor }else minimize_(qh min_vertex, dist); /* due to merge later */ } - trace2((qh ferr, "qh_findhorizon: point p%d is coplanar to horizon f%d, dist=%2.7g < qh MINvisible (%2.7g)\n", + 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; @@ -614,21 +618,21 @@ void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhor if (neighbor->good) (*goodhorizon)++; if (qh IStracing >=4) - qh_errprint ("horizon", neighbor, NULL, NULL, NULL); + qh_errprint("horizon", neighbor, NULL, NULL, NULL); } } } if (!numhorizon) { - qh_precision ("empty horizon"); - fprintf(qh ferr, "qhull precision error (qh_findhorizon): empty horizon\n\ -Point p%d was above all facets.\n", qh_pointid(point)); - qh_printfacetlist (qh facet_list, NULL, True); + qh_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, "qh_findhorizon: %d horizon facets (good %d), %d visible (good %d), %d coplanar\n", + 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 (); + qh_printlists(); } /* findhorizon */ /*-<a href="qh-qhull.htm#TOC" @@ -650,10 +654,10 @@ Point p%d was above all facets.\n", qh_pointid(point)); else if qh.NARROWhull determine furthest outside point if furthest point is not outside - advance qh.facet_next (point will be coplanar) + advance qh.facet_next(point will be coplanar) remove furthest point from outside set */ -pointT *qh_nextfurthest (facetT **visible) { +pointT *qh_nextfurthest(facetT **visible) { facetT *facet; int size, index; realT randr, dist; @@ -666,16 +670,16 @@ pointT *qh_nextfurthest (facetT **visible) { } SETreturnsize_(facet->outsideset, size); if (!size) { - qh_setfree (&facet->outsideset); + 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); + qh_furthestout(facet); + furthest= (pointT*)qh_setlast(facet->outsideset); #if qh_COMPUTEfurthest - qh_distplane (furthest, facet, &dist); + qh_distplane(furthest, facet, &dist); zinc_(Zcomputefurthest); #else dist= facet->furthestdist; @@ -687,11 +691,11 @@ pointT *qh_nextfurthest (facetT **visible) { } if (!qh RANDOMoutside && !qh VIRTUALmemory) { if (qh PICKfurthest) { - qh_furthestnext (/* qh facet_list */); + qh_furthestnext(/* qh facet_list */); facet= qh facet_next; } *visible= facet; - return ((pointT*)qh_setdellast (facet->outsideset)); + return((pointT*)qh_setdellast(facet->outsideset)); } if (qh RANDOMoutside) { int outcoplanar = 0; @@ -710,24 +714,24 @@ pointT *qh_nextfurthest (facetT **visible) { if (facet->outsideset) { SETreturnsize_(facet->outsideset, size); if (!size) - qh_setfree (&facet->outsideset); + qh_setfree(&facet->outsideset); else if (size > index) { *visible= facet; - return ((pointT*)qh_setdelnth (facet->outsideset, index)); + return((pointT*)qh_setdelnth(facet->outsideset, index)); }else index -= size; } } - fprintf (qh ferr, "qhull internal error (qh_nextfurthest): num_outside %d is too low\nby at least %d, or a random real %g >= 1.0\n", + qh_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, index+1, randr); - qh_errexit (qh_ERRqhull, NULL, NULL); + 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); + qh_setfree(&facet->outsideset); + qh_removefacet(facet); + qh_prependfacet(facet, &qh facet_list); continue; } *visible= facet; @@ -742,7 +746,7 @@ pointT *qh_nextfurthest (facetT **visible) { qh_partitionall( vertices, points, numpoints ) partitions all points in points/numpoints to the outsidesets of facets - vertices= vertices in qh.facet_list (not partitioned) + vertices= vertices in qh.facet_list(!partitioned) returns: builds facet->outsideset @@ -776,18 +780,18 @@ void qh_partitionall(setT *vertices, pointT *points, int numpoints){ facetT *facet; realT bestdist= -REALmax, dist, distoutside; - trace1((qh ferr, "qh_partitionall: partition all points into outside sets\n")); - pointset= qh_settemp (numpoints); + 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); + qh_settruncate(pointset, numpoints); FOREACHvertex_(vertices) { if ((id= qh_pointid(vertex->point)) >= 0) SETelem_(pointset, id)= NULL; } - id= qh_pointid (qh GOODpointp); + 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()*/ @@ -801,13 +805,13 @@ void qh_partitionall(setT *vertices, pointT *points, int numpoints){ point_end= numpoints; FORALLfacets { size= point_end/(remaining--) + 100; - facet->outsideset= qh_setnew (size); + facet->outsideset= qh_setnew(size); bestpoint= NULL; point_end= 0; FOREACHpoint_i_(pointset) { if (point) { zzinc_(Zpartitionall); - qh_distplane (point, facet, &dist); + qh_distplane(point, facet, &dist); if (dist < distoutside) SETelem_(pointset, point_end++)= point; else { @@ -816,22 +820,22 @@ void qh_partitionall(setT *vertices, pointT *points, int numpoints){ bestpoint= point; bestdist= dist; }else if (dist > bestdist) { - qh_setappend (&facet->outsideset, bestpoint); + qh_setappend(&facet->outsideset, bestpoint); bestpoint= point; bestdist= dist; }else - qh_setappend (&facet->outsideset, point); + qh_setappend(&facet->outsideset, point); } } } if (bestpoint) { - qh_setappend (&facet->outsideset, bestpoint); + qh_setappend(&facet->outsideset, bestpoint); #if !qh_COMPUTEfurthest facet->furthestdist= bestdist; #endif }else - qh_setfree (&facet->outsideset); - qh_settruncate (pointset, point_end); + qh_setfree(&facet->outsideset); + qh_settruncate(pointset, point_end); } } /* if !qh BESToutside, pointset contains points not assigned to outsideset */ @@ -847,7 +851,7 @@ void qh_partitionall(setT *vertices, pointT *points, int numpoints){ zzval_(Zpartition)= 0; qh_settempfree(&pointset); if (qh IStracing >= 4) - qh_printfacetlist (qh facet_list, NULL, True); + qh_printfacetlist(qh facet_list, NULL, True); } /* partitionall */ @@ -887,19 +891,19 @@ void qh_partitionall(setT *vertices, pointT *points, int numpoints){ else update qh.max_outside */ -void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) { +void qh_partitioncoplanar(pointT *point, facetT *facet, realT *dist) { facetT *bestfacet; pointT *oldfurthest; - realT bestdist, dist2, angle; + 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); + bestfacet= qh_findbestnew(point, facet, &bestdist, qh_ALL, &isoutside, &numpart); else - bestfacet= qh_findbest (point, facet, qh_ALL, !qh_ISnewfacets, qh DELAUNAY, + bestfacet= qh_findbest(point, facet, qh_ALL, !qh_ISnewfacets, qh DELAUNAY, &bestdist, &isoutside, &numpart); zinc_(Ztotpartcoplanar); zzadd_(Zpartcoplanar, numpart); @@ -907,12 +911,12 @@ void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) { if (qh KEEPnearinside) { if (bestdist < -qh NEARinside) { zinc_(Zcoplanarinside); - trace4((qh ferr, "qh_partitioncoplanar: point p%d is more than near-inside facet f%d dist %2.2g findbestnew %d\n", + 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, "qh_partitioncoplanar: point p%d is inside facet f%d dist %2.2g findbestnew %d\n", + 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; @@ -930,7 +934,7 @@ void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) { /* typically due to deleted vertex and coplanar facets, e.g., RBOX 1000 s Z1 G1e-13 t1001185205 | QHULL Tv */ zinc_(Zpartflip); - trace2((qh ferr, "qh_partitioncoplanar: repartition point p%d from f%d. It is above flipped facet f%d dist %2.2g\n", + 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; @@ -941,23 +945,23 @@ void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) { } qh max_outside= bestdist; if (bestdist > qh TRACEdist) { - fprintf (qh ferr, "qh_partitioncoplanar: ====== p%d from f%d increases max_outside to %2.2g of f%d last p%d\n", + qh_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); + qh_errprint("DISTANT", facet, bestfacet, NULL, NULL); } } if (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside) { - oldfurthest= (pointT*)qh_setlast (bestfacet->coplanarset); + oldfurthest= (pointT*)qh_setlast(bestfacet->coplanarset); if (oldfurthest) { zinc_(Zcomputefurthest); - qh_distplane (oldfurthest, bestfacet, &dist2); + qh_distplane(oldfurthest, bestfacet, &dist2); } if (!oldfurthest || dist2 < bestdist) qh_setappend(&bestfacet->coplanarset, point); else qh_setappend2ndlast(&bestfacet->coplanarset, point); } - trace4((qh ferr, "qh_partitioncoplanar: point p%d is coplanar with facet f%d (or inside) dist %2.2g\n", + 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 */ @@ -996,7 +1000,7 @@ void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) { if keeping inside points partition as coplanar point into bestfacet */ -void qh_partitionpoint (pointT *point, facetT *facet) { +void qh_partitionpoint(pointT *point, facetT *facet) { realT bestdist; boolT isoutside; facetT *bestfacet; @@ -1006,15 +1010,15 @@ void qh_partitionpoint (pointT *point, facetT *facet) { #endif if (qh findbestnew) - bestfacet= qh_findbestnew (point, facet, &bestdist, qh BESToutside, &isoutside, &numpart); + bestfacet= qh_findbestnew(point, facet, &bestdist, qh BESToutside, &isoutside, &numpart); else - bestfacet= qh_findbest (point, facet, qh BESToutside, qh_ISnewfacets, !qh_NOupper, + 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)"); + qh_precision("nearly incident point(narrow hull)"); if (qh KEEPnearinside) { if (bestdist >= -qh NEARinside) isoutside= True; @@ -1024,11 +1028,11 @@ void qh_partitionpoint (pointT *point, facetT *facet) { if (isoutside) { if (!bestfacet->outsideset - || !qh_setlast (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); + qh_removefacet(bestfacet); /* make sure it's after qh facet_next */ + qh_appendfacet(bestfacet); } #if !qh_COMPUTEfurthest bestfacet->furthestdist= bestdist; @@ -1036,7 +1040,7 @@ void qh_partitionpoint (pointT *point, facetT *facet) { }else { #if qh_COMPUTEfurthest zinc_(Zcomputefurthest); - qh_distplane (oldfurthest, bestfacet, &dist); + qh_distplane(oldfurthest, bestfacet, &dist); if (dist < bestdist) qh_setappend(&(bestfacet->outsideset), point); else @@ -1050,27 +1054,27 @@ void qh_partitionpoint (pointT *point, facetT *facet) { #endif } qh num_outside++; - trace4((qh ferr, "qh_partitionpoint: point p%d is outside facet f%d new? %d(or narrowhull)\n", + 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"); + qh_precision("nearly incident point"); if ((qh KEEPcoplanar + qh KEEPnearinside) || bestdist > qh max_outside) - qh_partitioncoplanar (point, bestfacet, &bestdist); + qh_partitioncoplanar(point, bestfacet, &bestdist); else { - trace4((qh ferr, "qh_partitionpoint: point p%d is coplanar to facet f%d (dropped)\n", + 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); + qh_partitioncoplanar(point, bestfacet, &bestdist); }else { zinc_(Zpartinside); - trace4((qh ferr, "qh_partitionpoint: point p%d is inside all facets, closest to f%d dist %2.2g\n", + 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); + qh_partitioncoplanar(point, bestfacet, &bestdist); } } /* partitionpoint */ @@ -1082,7 +1086,7 @@ void qh_partitionpoint (pointT *point, facetT *facet) { qh.visible_list= visible facets for visible facets 1st neighbor (if any) points to a horizon facet or a new facet - if allpoints (not used), + if allpoints(!used), repartitions coplanar points returns: @@ -1126,41 +1130,41 @@ void qh_partitionvisible(/*visible_list*/ boolT allpoints, int *numoutside) { while (newfacet && newfacet->visible) { newfacet= newfacet->f.replace; if (count++ > qh facet_id) - qh_infiniteloop (visible); + qh_infiniteloop(visible); } if (!newfacet) newfacet= qh newfacet_list; if (newfacet == qh facet_tail) { - fprintf (qh ferr, "qhull precision error (qh_partitionvisible): all new facets deleted as\n degenerate facets. Can not continue.\n"); - qh_errexit (qh_ERRprec, NULL, NULL); + 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); + size= qh_setsize(visible->outsideset); *numoutside += size; qh num_outside -= size; FOREACHpoint_(visible->outsideset) - qh_partitionpoint (point, newfacet); + qh_partitionpoint(point, newfacet); } if (visible->coplanarset && (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside)) { - size= qh_setsize (visible->coplanarset); + size= qh_setsize(visible->coplanarset); coplanar += size; FOREACHpoint_(visible->coplanarset) { if (allpoints) /* not used */ - qh_partitionpoint (point, newfacet); + qh_partitionpoint(point, newfacet); else - qh_partitioncoplanar (point, newfacet, NULL); + qh_partitioncoplanar(point, newfacet, NULL); } } } FOREACHvertex_(qh del_vertices) { if (vertex->point) { if (allpoints) /* not used */ - qh_partitionpoint (vertex->point, qh newfacet_list); + qh_partitionpoint(vertex->point, qh newfacet_list); else - qh_partitioncoplanar (vertex->point, qh newfacet_list, NULL); + qh_partitioncoplanar(vertex->point, qh newfacet_list, NULL); } } - trace1((qh ferr,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar)); + trace1((qh ferr, 1043,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar)); } /* partitionvisible */ @@ -1171,11 +1175,11 @@ void qh_partitionvisible(/*visible_list*/ boolT allpoints, int *numoutside) { qh_precision( reason ) restart on precision errors if not merging and if 'QJn' */ -void qh_precision (char *reason) { +void qh_precision(char *reason) { if (qh ALLOWrestart && !qh PREmerge && !qh MERGEexact) { if (qh JOGGLEmax < REALmax/2) { - trace0((qh ferr, "qh_precision: qhull restart because of %s\n", reason)); + trace0((qh ferr, 26, "qh_precision: qhull restart because of %s\n", reason)); longjmp(qh restartexit, qh_ERRprec); } } @@ -1205,9 +1209,9 @@ void qh_printsummary(FILE *fp) { 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); + 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); @@ -1222,7 +1226,7 @@ void qh_printsummary(FILE *fp) { if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id) size--; if (qh STOPcone || qh STOPpoint) - fprintf (fp, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error."); + qh_fprintf(fp, 9288, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error."); if (qh UPPERdelaunay) goodused= qh GOODvertex + qh GOODpoint + qh SPLITthresholds; else if (qh DELAUNAY) @@ -1232,49 +1236,49 @@ void qh_printsummary(FILE *fp) { nummerged= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot); if (qh VORONOI) { if (qh UPPERdelaunay) - fprintf (fp, "\n\ + 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 - fprintf (fp, "\n\ + qh_fprintf(fp, 9290, "\n\ Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim); - fprintf(fp, " Number of Voronoi regions%s: %d\n", + qh_fprintf(fp, 9291, " Number of Voronoi regions%s: %d\n", qh ATinfinity ? " and at-infinity" : "", numvertices); if (numdel) - fprintf(fp, " Total number of deleted points due to merging: %d\n", numdel); + qh_fprintf(fp, 9292, " Total number of deleted points due to merging: %d\n", numdel); if (numcoplanars - numdel > 0) - fprintf(fp, " Number of nearly incident points: %d\n", numcoplanars - numdel); + qh_fprintf(fp, 9293, " Number of nearly incident points: %d\n", numcoplanars - numdel); else if (size - numvertices - numdel > 0) - fprintf(fp, " Total number of nearly incident points: %d\n", size - numvertices - numdel); - fprintf(fp, " Number of%s Voronoi vertices: %d\n", + 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) - fprintf(fp, " Number of%s non-simplicial Voronoi vertices: %d\n", + qh_fprintf(fp, 9296, " Number of%s non-simplicial Voronoi vertices: %d\n", goodused ? " 'good'" : "", nonsimplicial); }else if (qh DELAUNAY) { if (qh UPPERdelaunay) - fprintf (fp, "\n\ + 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 - fprintf (fp, "\n\ + qh_fprintf(fp, 9298, "\n\ Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim); - fprintf(fp, " Number of input sites%s: %d\n", + qh_fprintf(fp, 9299, " Number of input sites%s: %d\n", qh ATinfinity ? " and at-infinity" : "", numvertices); if (numdel) - fprintf(fp, " Total number of deleted points due to merging: %d\n", numdel); + qh_fprintf(fp, 9300, " Total number of deleted points due to merging: %d\n", numdel); if (numcoplanars - numdel > 0) - fprintf(fp, " Number of nearly incident points: %d\n", numcoplanars - numdel); + qh_fprintf(fp, 9301, " Number of nearly incident points: %d\n", numcoplanars - numdel); else if (size - numvertices - numdel > 0) - fprintf(fp, " Total number of nearly incident points: %d\n", size - numvertices - numdel); - fprintf(fp, " Number of%s Delaunay regions: %d\n", + 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) - fprintf(fp, " Number of%s non-simplicial Delaunay regions: %d\n", + qh_fprintf(fp, 9304, " Number of%s non-simplicial Delaunay regions: %d\n", goodused ? " 'good'" : "", nonsimplicial); }else if (qh HALFspace) { - fprintf (fp, "\n\ + qh_fprintf(fp, 9305, "\n\ Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim); - fprintf(fp, " Number of halfspaces: %d\n", size); - fprintf(fp, " Number of non-redundant halfspaces: %d\n", numvertices); + 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"; @@ -1282,18 +1286,18 @@ Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh h s= "redundant"; else s= "similar"; - fprintf(fp, " Number of %s halfspaces: %d\n", s, numcoplanars); + qh_fprintf(fp, 9308, " Number of %s halfspaces: %d\n", s, numcoplanars); } - fprintf(fp, " Number of intersection points: %d\n", qh num_facets - qh num_visible); + qh_fprintf(fp, 9309, " Number of intersection points: %d\n", qh num_facets - qh num_visible); if (goodused) - fprintf(fp, " Number of 'good' intersection points: %d\n", qh num_good); + qh_fprintf(fp, 9310, " Number of 'good' intersection points: %d\n", qh num_good); if (nonsimplicial) - fprintf(fp, " Number of%s non-simplicial intersection points: %d\n", + qh_fprintf(fp, 9311, " Number of%s non-simplicial intersection points: %d\n", goodused ? " 'good'" : "", nonsimplicial); }else { - fprintf (fp, "\n\ + qh_fprintf(fp, 9312, "\n\ Convex hull of %d points in %d-d:\n\n", size, qh hull_dim); - fprintf(fp, " Number of vertices: %d\n", numvertices); + qh_fprintf(fp, 9313, " Number of vertices: %d\n", numvertices); if (numcoplanars) { if (qh KEEPinside && qh KEEPcoplanar) s= "coplanar and interior"; @@ -1301,96 +1305,96 @@ Convex hull of %d points in %d-d:\n\n", size, qh hull_dim); s= "interior"; else s= "coplanar"; - fprintf(fp, " Number of %s points: %d\n", s, numcoplanars); + qh_fprintf(fp, 9314, " Number of %s points: %d\n", s, numcoplanars); } - fprintf(fp, " Number of facets: %d\n", qh num_facets - qh num_visible); + qh_fprintf(fp, 9315, " Number of facets: %d\n", qh num_facets - qh num_visible); if (goodused) - fprintf(fp, " Number of 'good' facets: %d\n", qh num_good); + qh_fprintf(fp, 9316, " Number of 'good' facets: %d\n", qh num_good); if (nonsimplicial) - fprintf(fp, " Number of%s non-simplicial facets: %d\n", + qh_fprintf(fp, 9317, " Number of%s non-simplicial facets: %d\n", goodused ? " 'good'" : "", nonsimplicial); } if (numtricoplanars) - fprintf(fp, " Number of triangulated facets: %d\n", numtricoplanars); - fprintf(fp, "\nStatistics for: %s | %s", + qh_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) - fprintf(fp, " QR%d\n\n", qh ROTATErandom); + qh_fprintf(fp, 9320, " QR%d\n\n", qh ROTATErandom); else - fprintf(fp, "\n\n"); - fprintf(fp, " Number of points processed: %d\n", zzval_(Zprocessed)); - fprintf(fp, " Number of hyperplanes created: %d\n", zzval_(Zsetplane)); + 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) - fprintf(fp, " Number of facets in hull: %d\n", qh num_facets - qh num_visible); - fprintf(fp, " Number of distance tests for qhull: %d\n", zzval_(Zpartition)+ + 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; - fprintf(fp, " average new facet balance: %2.2g\n", + qh_fprintf(fp, 9326, " average new facet balance: %2.2g\n", wval_(Wnewbalance)/zval_(Zprocessed)); - stddev= qh_stddev (zval_(Zprocessed), wval_(Wnewbalance), + stddev= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance), wval_(Wnewbalance2), &ave); - fprintf(fp, " new facet standard deviation: %2.2g\n", stddev); - fprintf(fp, " average partition balance: %2.2g\n", + 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), + stddev= qh_stddev(zval_(Zpbalance), wval_(Wpbalance), wval_(Wpbalance2), &ave); - fprintf(fp, " partition standard deviation: %2.2g\n", stddev); + qh_fprintf(fp, 9329, " partition standard deviation: %2.2g\n", stddev); } #endif if (nummerged) { - fprintf(fp," Number of distance tests for merging: %d\n",zzval_(Zbestdist)+ + qh_fprintf(fp, 9330," Number of distance tests for merging: %d\n",zzval_(Zbestdist)+ zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+ zzval_(Zdistzero)); - fprintf(fp," Number of distance tests for checking: %d\n",zzval_(Zcheckpart)); - fprintf(fp," Number of merged facets: %d\n", nummerged); + 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= qh hulltime; + cpu= (float)qh hulltime; cpu /= qh_SECticks; wval_(Wcpu)= cpu; - fprintf (fp, " CPU seconds to compute hull (after input): %2.4g\n", cpu); + qh_fprintf(fp, 9333, " CPU seconds to compute hull(after input): %2.4g\n", cpu); } if (qh RERUN) { if (!qh PREmerge && !qh MERGEexact) - fprintf(fp, " Percentage of runs with precision errors: %4.1f\n", + 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)) - fprintf(fp, " After %d retries, input joggled by: %2.2g\n", + qh_fprintf(fp, 9335, " After %d retries, input joggled by: %2.2g\n", zzval_(Zretry), qh JOGGLEmax); else - fprintf(fp, " Input joggled by: %2.2g\n", qh JOGGLEmax); + qh_fprintf(fp, 9336, " Input joggled by: %2.2g\n", qh JOGGLEmax); } if (qh totarea != 0.0) - fprintf(fp, " %s facet area: %2.8g\n", + qh_fprintf(fp, 9337, " %s facet area: %2.8g\n", zzval_(Ztotmerge) ? "Approximate" : "Total", qh totarea); if (qh totvol != 0.0) - fprintf(fp, " %s volume: %2.8g\n", + qh_fprintf(fp, 9338, " %s volume: %2.8g\n", zzval_(Ztotmerge) ? "Approximate" : "Total", qh totvol); if (qh MERGING) { - qh_outerinner (NULL, &outerplane, &innerplane); + qh_outerinner(NULL, &outerplane, &innerplane); if (outerplane > 2 * qh DISTround) { - fprintf(fp, " Maximum distance of %spoint above facet: %2.2g", + 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) - fprintf (fp, " (%.1fx)\n", ratio); + qh_fprintf(fp, 9340, " (%.1fx)\n", ratio); else - fprintf (fp, "\n"); + qh_fprintf(fp, 9341, "\n"); } if (innerplane < -2 * qh DISTround) { - fprintf(fp, " Maximum distance of %svertex below facet: %2.2g", + 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) - fprintf (fp, " (%.1fx)\n", ratio); + qh_fprintf(fp, 9343, " (%.1fx)\n", ratio); else - fprintf (fp, "\n"); + qh_fprintf(fp, 9344, "\n"); } } - fprintf(fp, "\n"); + qh_fprintf(fp, 9345, "\n"); } /* printsummary */ diff --git a/src/qhulllib.h b/src/qhulllib.h new file mode 100644 index 0000000..abcb8e5 --- /dev/null +++ b/src/qhulllib.h @@ -0,0 +1,1094 @@ +/*<html><pre> -<a href="qh-qhull.htm" + >-------------------------------</a><a name="TOP">-</a> + + qhulllib.h + user-level header file for using qhull.a library + + see qh-qhull.htm, qhull_a.h + + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/qhulllib.h#8 $$Change: 1096 $ + $DateTime: 2009/12/04 21:52:01 $$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 qhulllib.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 qhulllib.h + + recompile qhull if you change this file +*/ + +#ifndef qhDEFqhulllib +#define qhDEFqhulllib 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 qhulllib.h +#endif +#endif +#endif + +#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */ +#pragma warning( disable : 4224) /* FIXUP? nonstandard extension used : formal parameter 'errcode' was previously defined as a type. [errcode was replaced by errno_t] */ +#endif + +/*============ constants and basic types ====================*/ + +extern 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 +*/ +#define pointT coordT + +/*-<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 +*/ +#define boolT unsigned int +#ifdef False +#undef False +#endif +#ifdef True +#undef True +#endif +#define False 0 +#define 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 qh names. The similar names are only + used in switch statements in qh_printbegin() etc. +*/ +typedef enum {qh_PRINTnone= 0, + qh_PRINTarea, qh_PRINTaverage, /* 'Fa' 'FV' 'Fc' 'FC' */ + qh_PRINTcoplanars, qh_PRINTcentrums, + qh_PRINTfacets, qh_PRINTfacets_xridge, /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */ + qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, + qh_PRINTnormals, qh_PRINTouter, 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 defines ridge */ + setT *neighbors; /* neighbors of the facet. If simplicial, the kth + neighbor is opposite the kth vertex, and the first + neighbor is the horizon facet for the first vertex*/ + setT *outsideset; /* set of points outside this facet + if non-empty, last point is furthest + if NARROWhull, includes coplanars for partitioning*/ + setT *coplanarset; /* set of points coplanar with this facet + > qh.min_vertex and <= facet->max_outside + a point is assigned to the furthest facet + if non-empty, last point is furthest away */ + unsigned visitid; /* visit_id, for visiting all neighbors, + all uses are independent */ + unsigned id; /* unique identifier from qh facet_id */ + unsigned nummerge:9; /* number of merges */ +#define qh_MAXnummerge 511 /* 2^9-1, 32 flags total, see "flags:" in io.c */ + flagT tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */ + /* all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */ + /* all tricoplanars share the same apex */ + /* if ->degenerate, does not span facet (one logical ridge) */ + /* one tricoplanar has ->keepcentrum and ->coplanarset */ + /* during qh_triangulate, f.trivisible points to original facet */ + flagT newfacet:1; /* True if facet on qh newfacet_list (new or merged) */ + flagT visible:1; /* True if visible facet (will be deleted) */ + flagT toporient:1; /* True if created with top orientation + after merging, use ridge orientation */ + flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */ + flagT seen:1; /* used to perform operations only once, like visitid */ + flagT seen2:1; /* used to perform operations only once, like visitid */ + flagT flipped:1; /* True if facet is flipped */ + flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */ + flagT notfurthest:1; /* True if last point of outsideset is not furthest*/ + +/*-------- flags primarily for output ---------*/ + flagT good:1; /* True if a facet marked good for output */ + flagT isarea:1; /* True if facet->f.area is defined */ + +/*-------- flags for merging ------------------*/ + flagT dupridge:1; /* True if duplicate ridge in facet */ + flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge + ->normal defined (also defined for mergeridge2) */ + flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */ + flagT coplanar:1; /* True if horizon facet is coplanar at last use */ + flagT mergehorizon:1; /* True if will merge into horizon (->coplanar) */ + flagT cycledone:1;/* True if mergecycle_all already done */ + flagT tested:1; /* True if facet convexity has been tested (false after merge */ + flagT keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */ + flagT newmerge:1; /* True if facet is newly merged for reducevertices */ + flagT degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */ + flagT redundant:1; /* True if facet is redundant (degen_mergeset) */ +}; + + +/*-<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 */ + 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 */ + flagT seen2:1; /* another seen flag */ + unsigned id:24; /* unique identifier */ + unsigned dim:4; /* dimension of point if non-zero, used by cpp */ + /* =>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 */ +}; + +#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. + + notes: + Qhull is not multithreaded. Global state could be stored in thread-local storage. +*/ + +extern int qhull_inuse; + +typedef struct qhT qhT; +#if qh_QHpointer +#define qh qh_qh-> +extern qhT *qh_qh; /* allocated in global.c */ +#else +#define qh qh_qh. +extern qhT qh_qh; +#endif + +struct qhT { + +/*-<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 */ + 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 */ + 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; /* 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; /* 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 */ + void *old_qhstat; /* for saving qh_qhstat in save_qhull() and UsingQhullLib. 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 ID for facet, ridge, or vertex + return MAXINT if NULL (-1 causes type conversion error ) +*/ +#define getid_(p) ((p) ? (p)->id : -1) + +/*============== 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) + +/********* -qhulllib.c prototypes (duplicated from qhull_a.h) **********************/ + +void qh_qhull(void); +boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist); +void qh_printsummary(FILE *fp); + +/********* -user.c prototypes (alphabetical) **********************/ + +void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge); +void qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex); +int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc, + char *qhull_cmd, FILE *outfile, FILE *errfile); +void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall); +void qh_printhelp_degenerate(FILE *fp); +void qh_printhelp_narrowhull(FILE *fp, realT minangle); +void qh_printhelp_singular(FILE *fp); +void qh_user_memsizes(void); + +/********* -user2.c prototypes (alphabetical) **********************/ +void qh_exit(int errcode); +void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ); +void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ); +void qh_free(void *mem); +void *qh_malloc(unsigned int size); + +/***** -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_option(char *option, int *i, realT *r); +#if qh_QHpointer +void qh_restore_qhull(qhT **oldqh); +qhT *qh_save_qhull(void); +#endif + +/***** -io.c prototypes (duplicated from io.h) ***********************/ + +void dfacet( unsigned id); +void dvertex( unsigned id); +void qh_printneighborhood(FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall); +void qh_produce_output(void); +coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc); + + +/********* -mem.c prototypes (duplicated from mem.h) **********************/ + +void qh_meminit(FILE *ferr); +void qh_memfreeshort(int *curlong, int *totlong); + +/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/ + +void qh_check_output(void); +void qh_check_points(void); +setT *qh_facetvertices(facetT *facetlist, setT *facets, boolT allfacets); +facetT *qh_findbestfacet(pointT *point, boolT bestoutside, + realT *bestdist, boolT *isoutside); +vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp); +pointT *qh_point(int id); +setT *qh_pointfacet(void /*qh.facet_list*/); +int qh_pointid(pointT *point); +setT *qh_pointvertex(void /*qh.facet_list*/); +void qh_setvoronoi_all(void); +void qh_triangulate(void /*qh facet_list*/); + +/********* -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, char *string); + +#endif /* qhDEFqhulllib */ diff --git a/src/qset.c b/src/qset.c index f902ea7..7cbe5c1 100644 --- a/src/qset.c +++ b/src/qset.c @@ -1,42 +1,39 @@ + /*<html><pre> -<a href="qh-set.htm" >-------------------------------</a><a name="TOP">-</a> - qset.c - implements set manipulations needed for quickhull + qset.c + implements set manipulations needed for quickhull see qh-set.htm and qset.h - copyright (c) 1993-2003 The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/qset.c#23 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ +#include "qset.h" +#include "mem.h" #include <stdio.h> #include <string.h> -/*** uncomment here and qhull_a.h +/*** uncomment here and qhull_a.h if string.h does not define memcpy() #include <memory.h> */ -#include "qset.h" -#include "mem.h" -#ifndef qhDEFqhull +#ifndef qhDEFqhulllib typedef struct ridgeT ridgeT; typedef struct facetT facetT; void qh_errexit(int exitcode, facetT *, ridgeT *); +void qh_fprintf(FILE *fp, int msgcode, 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 ===========================*/ -/*-<a href="qh-set.htm#TOC" - >-------------------------------<a name="SETsizeaddr_">-</a> - - SETsizeaddr_(set) - return pointer to actual size+1 of set (set CANNOT be NULL!!) - - notes: - *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL -*/ -#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize].i)) - /*============ functions in alphabetical order ===================*/ /*-<a href="qh-set.htm#TOC" @@ -50,7 +47,7 @@ void qh_errexit(int exitcode, facetT *, ridgeT *); *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 @@ -66,14 +63,14 @@ void qh_setaddnth(setT **setp, int nth, void *newelem) { } oldsize= *sizep - 1; if (nth < 0 || nth > oldsize) { - fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); - qh_setprint (qhmem.ferr, "", *setp); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + 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)++; oldp= SETelemaddr_(*setp, oldsize, void); /* NULL */ newp= oldp+1; - for (i= oldsize-nth+1; i--; ) /* move at least NULL */ + for (i=oldsize-nth+1; i--; ) /* move at least NULL */ *(newp--)= *(oldp--); /* may overwrite *sizep */ *newp= newelem; } /* setaddnth */ @@ -162,7 +159,7 @@ void qh_setappend_set(setT **setp, setT *setA) { return; SETreturnsize_(setA, sizeA); if (!*setp) - *setp= qh_setnew (sizeA); + *setp= qh_setnew(sizeA); sizep= SETsizeaddr_(*setp); if (!(size= *sizep)) size= (*setp)->maxsize; @@ -170,8 +167,8 @@ void qh_setappend_set(setT **setp, setT *setA) { size--; if (size + sizeA > (*setp)->maxsize) { oldset= *setp; - *setp= qh_setcopy (oldset, sizeA); - qh_setfree (&oldset); + *setp= qh_setcopy(oldset, sizeA); + qh_setfree(&oldset); sizep= SETsizeaddr_(*setp); } *sizep= size+sizeA+1; /* memcpy may overwrite */ @@ -231,17 +228,17 @@ void qh_setcheck(setT *set, char *tname, int id) { SETreturnsize_(set, size); maxsize= set->maxsize; if (size > maxsize || !maxsize) { - fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): actual size %d of %s%d is greater than max size %d\n", + 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) { - fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): %s%d (size %d max %d) is not null terminated.\n", + qh_fprintf(qhmem.ferr, 6173, "qhull internal error (qh_setcheck): %s%d(size %d max %d) is not null terminated.\n", tname, id, maxsize, size-1); waserr= 1; } if (waserr) { - qh_setprint (qhmem.ferr, "ERRONEOUS", set); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_setprint(qhmem.ferr, "ERRONEOUS", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } } /* setcheck */ @@ -280,7 +277,7 @@ void qh_setcompact(setT *set) { break; } } - qh_settruncate (set, destp-firstp); + qh_settruncate(set, (int)(destp-firstp)); /* WARN64 */ } /* setcompact */ @@ -308,7 +305,7 @@ setT *qh_setcopy(setT *set, int extra) { newset= qh_setnew(size+extra); *SETsizeaddr_(newset)= size+1; /* memcpy may overwrite */ memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), SETelemsize *(size+1)); - return (newset); + return(newset); } /* setcopy */ @@ -421,9 +418,9 @@ void *qh_setdelnth(setT *set, int nth) { if (!(*sizep)--) /* if was a full set */ *sizep= set->maxsize; /* *sizep= (maxsize-1)+ 1 */ if (nth < 0 || nth >= *sizep) { - fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); - qh_setprint (qhmem.ferr, "", set); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_fprintf(qhmem.ferr, 6174, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); + qh_setprint(qhmem.ferr, "", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } lastp= SETelemaddr_(set, *sizep-1, void); elem= *elemp; @@ -458,9 +455,9 @@ void *qh_setdelnthsorted(setT *set, int nth) { sizep= SETsizeaddr_(set); if (nth < 0 || (*sizep && nth >= *sizep-1) || nth >= set->maxsize) { - fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); - qh_setprint (qhmem.ferr, "", set); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_fprintf(qhmem.ferr, 6175, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); + qh_setprint(qhmem.ferr, "", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } newp= SETelemaddr_(set, nth, void); elem= *newp; @@ -497,7 +494,7 @@ void *qh_setdelsorted(setT *set, void *oldelem) { if (!set) return NULL; newp= SETaddr_(set, void); - while(*newp != oldelem && *newp) + while (*newp != oldelem && *newp) newp++; if (*newp) { oldp= newp+1; @@ -527,18 +524,18 @@ void *qh_setdelsorted(setT *set, void *oldelem) { create a newelem append newelem to newset */ -setT *qh_setduplicate (setT *set, int elemsize) { +setT *qh_setduplicate(setT *set, int elemsize) { void *elem, **elemp, *newElem; setT *newSet; int size; - if (!(size= qh_setsize (set))) + if (!(size= qh_setsize(set))) return NULL; - newSet= qh_setnew (size); + newSet= qh_setnew(size); FOREACHelem_(set) { - newElem= qh_memalloc (elemsize); - memcpy (newElem, elem, elemsize); - qh_setappend (&newSet, newElem); + newElem= qh_memalloc(elemsize); + memcpy(newElem, elem, elemsize); + qh_setappend(&newSet, newElem); } return newSet; } /* setduplicate */ @@ -596,7 +593,7 @@ int qh_setequal(setT *setA, setT *setB) { search for skipelemA, skipelemB, and mismatches check results */ -int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB) { +int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB) { void **elemA, **elemB; int skip=0; @@ -644,7 +641,7 @@ int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB setup pointers search for mismatches while skipping skipA and skipB */ -int qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB) { +int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB) { void **elemA, **elemB, **skipAp, **skipBp; elemA= SETaddr_(setA, void); @@ -692,7 +689,7 @@ void qh_setfree(setT **setp) { if (size <= qhmem.LASTsize) { qh_memfree_(*setp, size, freelistp); }else - qh_memfree (*setp, size); + qh_memfree(*setp, size); *setp= NULL; } } /* setfree */ @@ -715,8 +712,8 @@ void qh_setfree2 (setT **setp, int elemsize) { void *elem, **elemp; FOREACHelem_(*setp) - qh_memfree (elem, elemsize); - qh_setfree (setp); + qh_memfree(elem, elemsize); + qh_setfree(setp); } /* setfree2 */ @@ -743,7 +740,7 @@ void qh_setfreelong(setT **setp) { if (*setp) { size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; if (size > qhmem.LASTsize) { - qh_memfree (*setp, size); + qh_memfree(*setp, size); *setp= NULL; } } @@ -782,6 +779,7 @@ int qh_setin(setT *set, void *setelem) { notes: set may be NULL and may contain nulls. + NOerrors returned (qh_pointid, QhullPoint::id) design: checks maxsize @@ -879,7 +877,7 @@ void *qh_setlast(setT *set) { creates and allocates space for a set notes: - setsize means the number of elements (NOT including the NULL terminator) + setsize means the number of elements (!including the NULL terminator) use qh_settemp/qh_setfreetemp if set is temporary design: @@ -904,11 +902,11 @@ setT *qh_setnew(int setsize) { setsize += (sizereceived - size)/SETelemsize; #endif }else - set= (setT*)qh_memalloc (size); + set= (setT*)qh_memalloc(size); set->maxsize= setsize; set->e[setsize].i= 1; set->e[0].p= NULL; - return (set); + return(set); } /* setnew */ @@ -936,9 +934,9 @@ setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend) { int tailsize= size - nth -1, newsize; if (tailsize < 0) { - fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); - qh_setprint (qhmem.ferr, "", set); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_fprintf(qhmem.ferr, 6176, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth); + qh_setprint(qhmem.ferr, "", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } newsize= size-1 + prepend; newset= qh_setnew(newsize); @@ -1016,16 +1014,16 @@ void qh_setprint(FILE *fp, char* string, setT *set) { int size, k; if (!set) - fprintf (fp, "%s set is null\n", string); + qh_fprintf(fp, 9346, "%s set is null\n", string); else { SETreturnsize_(set, size); - fprintf (fp, "%s set=%p maxsize=%d size=%d elems=", + 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++) - fprintf(fp, " %p", set->e[k].p); - fprintf(fp, "\n"); + qh_fprintf(fp, 9348, " %p", set->e[k].p); + qh_fprintf(fp, 9349, "\n"); } } /* setprint */ @@ -1047,15 +1045,15 @@ void qh_setreplace(setT *set, void *oldelem, void *newelem) { void **elemp; elemp= SETaddr_(set, void); - while(*elemp != oldelem && *elemp) + while (*elemp != oldelem && *elemp) elemp++; if (*elemp) *elemp= newelem; else { - fprintf (qhmem.ferr, "qhull internal error (qh_setreplace): elem %p not found in set\n", + 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); + qh_setprint(qhmem.ferr, "", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } } /* setreplace */ @@ -1069,6 +1067,7 @@ void qh_setreplace(setT *set, void *oldelem, void *newelem) { 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 @@ -1077,15 +1076,15 @@ int qh_setsize(setT *set) { int size, *sizep; if (!set) - return (0); + return(0); sizep= SETsizeaddr_(set); if ((size= *sizep)) { size--; if (size > set->maxsize) { - fprintf (qhmem.ferr, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n", + 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); + qh_setprint(qhmem.ferr, "set: ", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } }else size= set->maxsize; @@ -1094,7 +1093,7 @@ int qh_setsize(setT *set) { /*-<a href="qh-set.htm#TOC" >-------------------------------<a name="settemp">-</a> - + qh_settemp( setsize ) return a stacked, temporary set of upto setsize elements @@ -1110,11 +1109,11 @@ int qh_setsize(setT *set) { setT *qh_settemp(int setsize) { setT *newset; - newset= qh_setnew (setsize); - qh_setappend ((setT **)&qhmem.tempstack, newset); + newset= qh_setnew(setsize); + qh_setappend((setT **)&qhmem.tempstack, newset); if (qhmem.IStracing >= 5) - fprintf (qhmem.ferr, "qh_settemp: temp set %p of %d elements, depth %d\n", - newset, newset->maxsize, qh_setsize ((setT*)qhmem.tempstack)); + qh_fprintf(qhmem.ferr, 8123, "qh_settemp: temp set %p of %d elements, depth %d\n", + newset, newset->maxsize, qh_setsize((setT*)qhmem.tempstack)); return newset; } /* settemp */ @@ -1140,15 +1139,15 @@ void qh_settempfree(setT **set) { if (!*set) return; - stackedset= qh_settemppop (); + stackedset= qh_settemppop(); if (stackedset != *set) { qh_settemppush(stackedset); - fprintf (qhmem.ferr, "qhull internal error (qh_settempfree): set %p (size %d) was not last temporary allocated (depth %d, set %p, size %d)\n", + 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((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset)); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } - qh_setfree (set); + qh_setfree(set); } /* settempfree */ /*-<a href="qh-set.htm#TOC" @@ -1165,7 +1164,7 @@ void qh_settempfree(setT **set) { void qh_settempfree_all(void) { setT *set, **setp; - FOREACHset_((setT *)qhmem.tempstack) + FOREACHset_((setT *)qhmem.tempstack) qh_setfree(&set); qh_setfree((setT **)&qhmem.tempstack); } /* settempfree_all */ @@ -1187,11 +1186,11 @@ setT *qh_settemppop(void) { stackedset= (setT*)qh_setdellast((setT *)qhmem.tempstack); if (!stackedset) { - fprintf (qhmem.ferr, "qhull internal error (qh_settemppop): pop from empty temporary stack\n"); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + 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) - fprintf (qhmem.ferr, "qh_settemppop: depth %d temp set %p of %d elements\n", + qh_fprintf(qhmem.ferr, 8124, "qh_settemppop: depth %d temp set %p of %d elements\n", qh_setsize((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset)); return stackedset; } /* settemppop */ @@ -1210,10 +1209,10 @@ setT *qh_settemppop(void) { */ void qh_settemppush(setT *set) { - qh_setappend ((setT**)&qhmem.tempstack, set); + qh_setappend((setT**)&qhmem.tempstack, set); if (qhmem.IStracing >= 5) - fprintf (qhmem.ferr, "qh_settemppush: depth %d temp set %p of %d elements\n", - qh_setsize((setT*)qhmem.tempstack), set, qh_setsize(set)); + qh_fprintf(qhmem.ferr, 8125, "qh_settemppush: depth %d temp set %p of %d elements\n", + qh_setsize((setT*)qhmem.tempstack), set, qh_setsize(set)); } /* settemppush */ @@ -1233,12 +1232,12 @@ void qh_settemppush(setT *set) { check size update actual size of set */ -void qh_settruncate (setT *set, int size) { +void qh_settruncate(setT *set, int size) { if (size < 0 || size > set->maxsize) { - fprintf (qhmem.ferr, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size); - qh_setprint (qhmem.ferr, "", set); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + 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; @@ -1257,10 +1256,10 @@ void qh_settruncate (setT *set, int size) { if elem not in set append elem to set */ -int qh_setunique (setT **set, void *elem) { +int qh_setunique(setT **set, void *elem) { - if (!qh_setin (*set, elem)) { - qh_setappend (set, elem); + if (!qh_setin(*set, elem)) { + qh_setappend(set, elem); return 1; } return 0; @@ -1285,17 +1284,17 @@ int qh_setunique (setT **set, void *elem) { update actual size zero elements starting at e[index] */ -void qh_setzero (setT *set, int index, int size) { +void qh_setzero(setT *set, int index, int size) { int count; if (index < 0 || index >= size || size > set->maxsize) { - fprintf (qhmem.ferr, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", index, size); - qh_setprint (qhmem.ferr, "", set); - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_fprintf(qhmem.ferr, 6182, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", index, size); + qh_setprint(qhmem.ferr, "", set); + qh_errexit(qhmem_ERRqhull, NULL, NULL); } set->e[set->maxsize].i= size+1; /* may be overwritten */ count= size - index + 1; /* +1 for NULL terminator */ - memset ((char *)SETelemaddr_(set, index, void), 0, count * SETelemsize); + memset((char *)SETelemaddr_(set, index, void), 0, count * SETelemsize); } /* setzero */ - + diff --git a/src/qset.h b/src/qset.h index 5752498..c188d6a 100644 --- a/src/qset.h +++ b/src/qset.h @@ -9,19 +9,23 @@ only uses mem.c, malloc/free for error handling, writes message and calls - qh_errexit (qhmem_ERRqhull, NULL, NULL); + qh_errexit(qhmem_ERRqhull, NULL, NULL); set operations satisfy the following properties: - sets have a max size, the actual size (if different) is stored at the end - every set is NULL terminated - sets may be sorted or unsorted, the caller must distinguish this - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/qset.h#16 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ */ #ifndef qhDEFset #define qhDEFset 1 +#include <stdio.h> + /*================= -structures- ===============*/ #ifndef DEFsetT @@ -129,7 +133,7 @@ struct setT { this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} ) */ #define FOREACHsetelement_(type, set, variable) \ - if (((variable= NULL), set)) for(\ + if (((variable= NULL), set)) for (\ variable##p= (type **)&((set)->e[0].p); \ (variable= *variable##p++);) @@ -195,7 +199,7 @@ struct setT { WARNING: needs braces if nested inside another FOREACH */ #define FOREACHsetelementreverse_(type, set, variable) \ - if (((variable= NULL), set)) for(\ + if (((variable= NULL), set)) for (\ variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\ variable; variable= \ ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL)) @@ -226,7 +230,7 @@ struct setT { WARNING: needs braces if nested inside another FOREACH */ #define FOREACHsetelementreverse12_(type, set, variable) \ - if (((variable= NULL), set)) for(\ + 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: \ @@ -294,11 +298,12 @@ struct setT { notes: for use with FOREACH iteration + WARN64 -- Maximum set size is 2G example: i= SETindex_(ridges, ridge) */ -#define SETindex_(set, elem) ((void **)elem##p - (void **)&(set)->e[1].p) +#define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p)) /*-<a href="qh-set.htm#TOC" >---------------------------------------</a><a name="SETref_">-</a> @@ -404,12 +409,23 @@ struct setT { >---------------------------------------</a><a name="SETempty_">-</a> SETempty_(set) - return true (1) if set is empty + return true(1) if set is empty notes: set may be NULL */ -#define SETempty_(set) (!set || (SETfirst_(set) ? 0:1)) +#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!!) + + notes: + *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL +*/ +#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize].i)) /*-<a href="qh-set.htm#TOC" >---------------------------------------</a><a name="SETtruncate_">-</a> @@ -441,8 +457,8 @@ void *qh_setdelnthsorted(setT *set, int nth); void *qh_setdelsorted(setT *set, void *newelem); setT *qh_setduplicate( setT *set, int elemsize); int qh_setequal(setT *setA, setT *setB); -int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB); -int qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB); +int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB); +int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB); void qh_setfree(setT **set); void qh_setfree2( setT **setp, int elemsize); void qh_setfreelong(setT **set); @@ -460,9 +476,9 @@ void qh_settempfree(setT **set); void qh_settempfree_all(void); setT *qh_settemppop(void); void qh_settemppush(setT *set); -void qh_settruncate (setT *set, int size); -int qh_setunique (setT **set, void *elem); -void qh_setzero (setT *set, int index, int size); +void qh_settruncate(setT *set, int size); +int qh_setunique(setT **set, void *elem); +void qh_setzero(setT *set, int index, int size); #endif /* qhDEFset */ diff --git a/src/qvoronoi.c b/src/qvoronoi.c index 1a3aeb4..10d7cf8 100644 --- a/src/qvoronoi.c +++ b/src/qvoronoi.c @@ -7,7 +7,7 @@ see unix.c for full interface - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2008, The Geometry Center */ #include <stdio.h> @@ -15,7 +15,7 @@ #include <string.h> #include <ctype.h> #include <math.h> -#include "qhull.h" +#include "qhulllib.h" #include "mem.h" #include "qset.h" @@ -27,7 +27,7 @@ #elif __cplusplus extern "C" { - int isatty (int); + int isatty(int); } #elif _MSC_VER @@ -35,7 +35,7 @@ extern "C" { #define isatty _isatty #else -int isatty (int); /* returns 1 if stdin is a tty +int isatty(int); /* returns 1 if stdin is a tty if "Undefined symbol" this can be deleted along with call in main() */ #endif @@ -46,7 +46,7 @@ int isatty (int); /* returns 1 if stdin is a tty long prompt for qhull notes: - restricted version of qhull.c + restricted version of qhulllib.c see: concise prompt below @@ -261,10 +261,10 @@ int main(int argc, char *argv[]) { 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"); + 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 @@ -281,21 +281,21 @@ int main(int argc, char *argv[]) { 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(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_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_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_option("_merge-exact", NULL, NULL); qh MERGEexact= True; /* 'Qx' always */ } - qh_init_B (points, numpoints, dim, ismalloc); + qh_init_B(points, numpoints, dim, ismalloc); qh_qhull(); qh_check_output(); qh_produce_output(); @@ -308,9 +308,9 @@ int main(int argc, char *argv[]) { qh_freeqhull( True); #else qh_freeqhull( False); - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) - fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", + fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); #endif return exitcode; diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..127a6f8 --- /dev/null +++ b/src/random.c @@ -0,0 +1,243 @@ +/*<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 +*/ + +#include "qhulllib.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: + qh_fprintf(qh ferr, 6033, "qhull input error: more than %d characters in command line\n", + max_size); + 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_rand_seed= 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_rand_seed; + + hi = seed / qh_rand_q; /* seed div q */ + lo = seed % qh_rand_q; /* seed mod q */ + test = qh_rand_a * lo - qh_rand_r * hi; + if (test > 0) + seed= test; + else + seed= test + qh_rand_m; + qh_rand_seed= seed; + /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */ + /* seed = qh_RANDOMmax; for testing */ + return seed; +} /* rand */ + +void qh_srand( int seed) { + if (seed < 1) + qh_rand_seed= 1; + else if (seed >= qh_rand_m) + qh_rand_seed= qh_rand_m - 1; + else + qh_rand_seed= seed; +} /* qh_srand */ + +/*-<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/random.h b/src/random.h new file mode 100644 index 0000000..11c3f92 --- /dev/null +++ b/src/random.h @@ -0,0 +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.c + + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/random.h#8 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ +*/ + +#ifndef qhDEFrandom +#define qhDEFrandom 1 + +#include "qhulllib.h" + +/*============= prototypes in alphabetical order ======= */ + + +int qh_argv_to_command(int argc, char *argv[], char* command, int max_size); +int qh_argv_to_command_size(int argc, char *argv[]); +int qh_rand( void); +void qh_srand( int seed); +realT qh_randomfactor(realT scale, realT offset); +void qh_randommatrix(realT *buffer, int dim, realT **row); +int qh_strtol(const char *s, char **endp); +double qh_strtod(const char *s, char **endp); + +#endif /* qhDEFrandom */ + + + diff --git a/src/rbox.c b/src/rbox.c index 1c288bd..4a31bfa 100644 --- a/src/rbox.c +++ b/src/rbox.c @@ -2,27 +2,20 @@ >-------------------------------</a><a name="TOP">-</a> rbox.c - Generate input points for qhull. + rbox program for generating input points for qhull. notes: 50 points generated for 'rbox D4' - This code needs a full rewrite. It needs separate procedures for each - distribution with common, helper procedures. - - WARNING: - incorrect range if qh_RANDOMmax is defined wrong (user.h) */ +#include "random.h" +#include "qhulllib.h" + +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <math.h> -#include <limits.h> -#include <time.h> -#include "user.h" #if __MWERKS__ && __POWERPC__ #include <SIOUX.h> #include <Files.h> @@ -30,15 +23,10 @@ #include <Desk.h> #endif -#ifdef _MSC_VER /* Microsoft Visual C++ */ -#pragma warning( disable : 4244) /* conversion from double to int */ +#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */ +#pragma warning( disable : 4706) /* assignment within conditional function */ #endif -#define MINVALUE 0.8 -#define MAXdim 200 -#define PI 3.1415926535897932384 -#define DEFAULTzbox 1e6 - char prompt[]= "\n\ -rbox- generate various point distributions. Default is random in cube.\n\ \n\ @@ -55,7 +43,7 @@ args (any order, space separated): Version: 2001/06/24\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\ + 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\ @@ -65,724 +53,45 @@ args (any order, space separated): Version: 2001/06/24\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\ + t use time as the random number seed(default is command line)\n\ tn use n as the random number seed\n\ z print integer coordinates, default 'Bn' is %2.2g\n\ "; -/* ------------------------------ prototypes ----------------*/ -int roundi( double a); -void out1( double a); -void out2n( double a, double b); -void out3n( double a, double b, double c); -int qh_rand( void); -void qh_srand( int seed); - - -/* ------------------------------ globals -------------------*/ - - FILE *fp; - int isinteger= 0; - double out_offset= 0.0; - - /*-------------------------------------------- -rbox- main procedure of rbox application */ int main(int argc, char **argv) { - int i,j,k; - int gendim; - int cubesize, diamondsize, seed=0, count, apex; - int dim=3 , numpoints= 0, totpoints, addpoints=0; - int issphere=0, isaxis=0, iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0; - int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0, istime=0; - int isbox=0, issimplex=0, issimplex2=0, ismesh=0; - double width=0.0, gap=0.0, radius= 0.0; - double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0; - double *simplex, *simplexp; - int nthroot, mult[MAXdim]; - double norm, factor, randr, rangap, lensangle= 0, lensbase= 1; - double anglediff, angle, x, y, cube= 0.0, diamond= 0.0; - double box= qh_DEFAULTbox; /* scale all numbers before output */ - double randmax= qh_RANDOMmax; - char command[200], *s, seedbuf[200]; - time_t timedata; + 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); + char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ]; + SIOUXSettings.showstatusline= False; + SIOUXSettings.tabspaces= 1; + SIOUXSettings.rows= 40; + if (setvbuf(stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0 /* w/o, SIOUX I/O is slow*/ + || setvbuf(stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0 + || (stdout != stderr && setvbuf(stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) + fprintf(stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n"); + argc= ccommand(&argv); #endif - if (argc == 1) { - printf (prompt, box, DEFAULTzbox); - exit(1); - } - if ((s = strrchr( argv[0], '\\'))) /* Borland gives full path */ - strcpy (command, s+1); - else - strcpy (command, argv[0]); - if ((s= strstr (command, ".EXE")) - || (s= strstr (command, ".exe"))) - *s= '\0'; - /* ============= read flags =============== */ - for (i=1; i < argc; i++) { - if (strlen (command) + strlen(argv[i]) + 1 < sizeof(command) ) { - strcat (command, " "); - strcat (command, argv[i]); - } - if (isdigit (argv[i][0])) { - numpoints= atoi (argv[i]); - continue; - } - if (argv[i][0] == '-') - (argv[i])++; - switch (argv[i][0]) { - case 'c': - addcube= 1; - if (i+1 < argc && argv[i+1][0] == 'G') - cube= (double) atof (&argv[++i][1]); - break; - case 'd': - adddiamond= 1; - if (i+1 < argc && argv[i+1][0] == 'G') - diamond= (double) atof (&argv[++i][1]); - break; - case 'h': - iscdd= 1; - break; - case 'l': - isspiral= 1; - break; - case 'n': - NOcommand= 1; - break; - case 'r': - isregular= 1; - break; - case 's': - issphere= 1; - break; - case 't': - istime= 1; - if (isdigit (argv[i][1])) - seed= atoi (&argv[i][1]); - else { - seed= time (&timedata); - sprintf (seedbuf, "%d", seed); - strcat (command, seedbuf); - } - break; - case 'x': - issimplex= 1; - break; - case 'y': - issimplex2= 1; - break; - case 'z': - isinteger= 1; - break; - case 'B': - box= (double) atof (&argv[i][1]); - isbox= 1; - break; - case 'D': - dim= atoi (&argv[i][1]); - if (dim < 1 - || dim > MAXdim) { - fprintf (stderr, "rbox error: dim %d too large or too small\n", dim); - exit (1); - } - break; - case 'G': - if (argv[i][1]) - gap= (double) atof (&argv[i][1]); - else - gap= 0.5; - isgap= 1; - break; - case 'L': - if (argv[i][1]) - radius= (double) atof (&argv[i][1]); - else - radius= 10; - islens= 1; - break; - case 'M': - ismesh= 1; - s= argv[i]+1; - if (*s) - meshn= strtod (s, &s); - if (*s == ',') - meshm= strtod (++s, &s); - else - meshm= 0.0; - if (*s == ',') - meshr= strtod (++s, &s); - else - meshr= sqrt (meshn*meshn + meshm*meshm); - if (*s) { - fprintf (stderr, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n"); - meshn= 3.0, meshm=4.0, meshr=5.0; - } - break; - case 'O': - out_offset= (double) atof (&argv[i][1]); - break; - case 'P': - addpoints++; - break; - case 'W': - width= (double) atof (&argv[i][1]); - iswidth= 1; - break; - case 'Z': - if (argv[i][1]) - radius= (double) atof (&argv[i][1]); - else - radius= 1.0; - isaxis= 1; - break; - default: - fprintf (stderr, "rbox warning: unknown flag %s.\nExecute 'rbox' without arguments for documentation.\n", argv[i]); - } - } - /* ============= defaults, constants, and sizes =============== */ - if (isinteger && !isbox) - box= DEFAULTzbox; - if (addcube) { - cubesize= floor(ldexp(1.0,dim)+0.5); - if (cube == 0.0) - cube= box; - }else - cubesize= 0; - if (adddiamond) { - diamondsize= 2*dim; - if (diamond == 0.0) - diamond= box; - }else - diamondsize= 0; - if (islens) { - if (isaxis) { - fprintf (stderr, "rbox error: can not combine 'Ln' with 'Zn'\n"); - exit(1); - } - if (radius <= 1.0) { - fprintf (stderr, "rbox error: lens radius %.2g should be greater than 1.0\n", - radius); - exit(1); - } - lensangle= asin (1.0/radius); - lensbase= radius * cos (lensangle); - } - if (!numpoints) { - if (issimplex2) - ; /* ok */ - else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) { - fprintf (stderr, "rbox error: missing count\n"); - exit(1); - }else if (adddiamond + addcube + addpoints) - ; /* ok */ - else { - numpoints= 50; /* ./rbox D4 is the test case */ - issphere= 1; - } - } - if ((issimplex + islens + isspiral + ismesh > 1) - || (issimplex + issphere + isspiral + ismesh > 1)) { - fprintf (stderr, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n"); - exit(1); - } - fp= stdout; - /* ============= print header with total points =============== */ - if (issimplex || ismesh) - totpoints= numpoints; - else if (issimplex2) - totpoints= numpoints+dim+1; - else if (isregular) { - totpoints= numpoints; - if (dim == 2) { - if (islens) - totpoints += numpoints - 2; - }else if (dim == 3) { - if (islens) - totpoints += 2 * numpoints; - else if (isgap) - totpoints += 1 + numpoints; - else - totpoints += 2; - } - }else - totpoints= numpoints + isaxis; - totpoints += cubesize + diamondsize + addpoints; - if (iscdd) - fprintf(fp, "%s\nbegin\n %d %d %s\n", - NOcommand ? "" : command, - totpoints, dim+1, - isinteger ? "integer" : "real"); - else if (NOcommand) - fprintf(fp, "%d\n%d\n", dim, totpoints); - else - fprintf(fp, "%d %s\n%d\n", dim, command, totpoints); - /* ============= seed randoms =============== */ - if (istime == 0) { - for (s=command; *s; s++) { - if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */ - i= 'x'; - else - i= *s; - seed= 11*seed + i; - } - } /* else, seed explicitly set to n or to time */ - qh_RANDOMseed_(seed); - /* ============= explicit points =============== */ - for (i=1; i < argc; i++) { - if (argv[i][0] == 'P') { - s= argv[i]+1; - count= 0; - if (iscdd) - out1( 1.0); - while (*s) { - out1( strtod (s, &s)); - count++; - if (*s) { - if (*s++ != ',') { - fprintf (stderr, "rbox error: missing comma after coordinate in %s\n\n", argv[i]); - exit (1); - } - } - } - if (count < dim) { - for (k= dim-count; k--; ) - out1( 0.0); - }else if (count > dim) { - fprintf (stderr, "rbox error: %d coordinates instead of %d coordinates in %s\n\n", - count, dim, argv[i]); - exit (1); - } - fprintf (fp, "\n"); - } - } - /* ============= simplex distribution =============== */ - if (issimplex+issimplex2) { - if (!(simplex= malloc( dim * (dim+1) * sizeof(double)))) { - fprintf (stderr, "insufficient memory for simplex\n"); - exit(0); - } - simplexp= simplex; - if (isregular) { - for (i= 0; i<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) - out1( 1.0); - for (k= 0; k<dim; k++) - out1( *(simplexp++) * box); - fprintf (fp, "\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) - out1( 1.0); - for (k=0; k < dim; k++) - out1( coord[k] * box); - fprintf (fp, "\n"); - } - isregular= 0; /* continue with isbox */ - numpoints= 0; - } - /* ============= mesh distribution =============== */ - if (ismesh) { - nthroot= pow (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) - out1( mult[0] * meshn + mult[1] * (-meshm)); - else if (k == 1) - out1( mult[0] * meshm + mult[1] * meshn); - else - out1( mult[k] * meshr ); - } - fprintf (fp, "\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) { - fprintf(stderr, "rbox error: regular points can be used only in 2-d and 3-d\n\n"); - exit(1); - } - if (!isaxis || radius == 0.0) { - isaxis= 1; - radius= 1.0; - } - if (dim == 3) { - if (iscdd) - out1( 1.0); - out3n( 0.0, 0.0, -box); - if (!isgap) { - if (iscdd) - out1( 1.0); - 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) - out1( 1.0); - out2n( x*box, y*box); - }else { - norm= sqrt (1.0 + x*x + y*y); - if (iscdd) - out1( 1.0); - 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) - out1( 1.0); - 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) - out1( 1.0); - out2n( x*box, y*box); - if (i != 0 && i != numpoints - 1) { - if (iscdd) - out1( 1.0); - out2n( x*box, -y*box); - } - } - } - /* ============= regular points for 'r Ln D3' =============== */ - else if (isregular && islens && dim != 2) { - if (dim != 3) { - fprintf(stderr, "rbox error: regular points can be used only in 2-d and 3-d\n\n"); - exit(1); - } - 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) - out1( 1.0); - out3n( box*x, box*y, 0); - x *= 1-gap; - y *= 1-gap; - if (iscdd) - out1( 1.0); - out3n( box*x, box*y, box * offset); - if (iscdd) - out1( 1.0); - out3n( box*x, box*y, -box * offset); - } - } - /* ============= apex of 'Zn' distribution + gendim =============== */ - else { - if (isaxis) { - gendim= dim-1; - if (iscdd) - out1( 1.0); - for (j=0; j < gendim; j++) - out1( 0.0); - out1( -box); - fprintf (fp, "\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) { - fprintf(stderr, "rbox error: spiral distribution is available only in 3d\n\n"); - exit(1); - } - 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) - out1( 1.0); - for (k=0; k < dim; k++) - out1( coord[k] * box); - fprintf (fp, "\n"); - } - } - /* ============= write cube vertices =============== */ - if (addcube) { - for (j=0; j<cubesize; j++) { - if (iscdd) - out1( 1.0); - for (k=dim-1; k>=0; k--) { - if (j & ( 1 << k)) - out1( cube); - else - out1( -cube); - } - fprintf (fp, "\n"); - } - } - /* ============= write diamond vertices =============== */ - if (adddiamond) { - for (j=0; j<diamondsize; j++) { - if (iscdd) - out1( 1.0); - for (k=dim-1; k>=0; k--) { - if (j/2 != k) - out1( 0.0); - else if (j & 0x1) - out1( diamond); - else - out1( -diamond); - } - fprintf (fp, "\n"); - } - } - if (iscdd) - fprintf (fp, "end\nhull\n"); - return 0; - } /* rbox */ + if (argc == 1) { + printf(prompt, qh_DEFAULTbox, qh_DEFAULTzbox); + return 1; + } -/*------------------------------------------------ --outxxx - output functions -*/ -int roundi( double a) { - if (a < 0.0) { - if (a - 0.5 < INT_MIN) { - fprintf(stderr, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a); - exit (1); - } - return a - 0.5; + command_size= qh_argv_to_command_size(argc, argv); + if ((command= (char *)qh_malloc(command_size))) { + qh_argv_to_command(argc, argv, command, command_size); + return_status= qh_rboxpoints(stdout, stderr, command); + qh_free(command); }else { - if (a + 0.5 > INT_MAX) { - fprintf(stderr, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a); - exit (1); - } - return a + 0.5; + fprintf(stderr, "rbox error: insufficient memory for %d bytes\n", command_size); + return_status= qh_ERRmem; } -} /* roundi */ - -void out1(double a) { - - if (isinteger) - fprintf(fp, "%d ", roundi( a+out_offset)); - else - fprintf(fp, qh_REAL_1, a+out_offset); -} /* out1 */ - -void out2n( double a, double b) { - - if (isinteger) - fprintf(fp, "%d %d\n", roundi(a+out_offset), roundi(b+out_offset)); - else - fprintf(fp, qh_REAL_2n, a+out_offset, b+out_offset); -} /* out2n */ - -void out3n( double a, double b, double c) { - - if (isinteger) - fprintf(fp, "%d %d %d\n", roundi(a+out_offset), roundi(b+out_offset), roundi(c+out_offset)); - else - fprintf(fp, qh_REAL_3n, a+out_offset, b+out_offset, c+out_offset); -} /* out3n */ - -/*------------------------------------------------- --rand & srand- generate pseudo-random number between 1 and 2^31 -2 - from Park & Miller's minimimal standard random number generator - Communications of the ACM, 31:1192-1201, 1988. -notes: - does not use 0 or 2^31 -1 - this is silently enforced by qh_srand() - copied from geom2.c -*/ -static int seed = 1; /* global static */ - -int qh_rand( void) { -#define qh_rand_a 16807 -#define qh_rand_m 2147483647 -#define qh_rand_q 127773 /* m div a */ -#define qh_rand_r 2836 /* m mod a */ - int lo, hi, test; - - hi = seed / qh_rand_q; /* seed div q */ - lo = seed % qh_rand_q; /* seed mod q */ - test = qh_rand_a * lo - qh_rand_r * hi; - if (test > 0) - seed= test; - else - seed= test + qh_rand_m; - return seed; -} /* rand */ - -void qh_srand( int newseed) { - if (newseed < 1) - seed= 1; - else if (newseed >= qh_rand_m) - seed= qh_rand_m - 1; - else - seed= newseed; -} /* qh_srand */ + return return_status; +}//main diff --git a/src/rboxlib.c b/src/rboxlib.c new file mode 100644 index 0000000..fcd146f --- /dev/null +++ b/src/rboxlib.c @@ -0,0 +1,788 @@ +/*<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 "qhulllib.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 : 4244) /* conversion from double to int */ +#pragma warning( disable : 4706) /* assignment within conditional expression. */ +#pragma warning( disable : 4996) /* this function or variable may be unsafe. */ +#endif + +#define MAXdim 200 +#define PI 3.1415926535897932384 + +/* ------------------------------ prototypes ----------------*/ +int roundi( double a); +void out1( double a); +void out2n( double a, double b); +void 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(unsigned int 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() */ +}; + + +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) + + 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 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; + + 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 */ + if (simplex) + qh_free(simplex); + rbox_inuse= False; + return exitcode; + } + + *command= '\0'; + strncat(command, rbox_command, sizeof(command)); + + 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_strtod(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 == ',') + meshm= qh_strtod(++s, &s); + else + meshm= 0.0; + if (*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= 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; + + 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(rbox.fout, 9393, "%d %s\n%d\n", dim, command, totpoints); + + /* ============= seed randoms =============== */ + if (istime == 0) { + for (s=command; *s; s++) { + if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */ + i= 'x'; + else + i= *s; + seed= 11*seed + i; + } + }else if (israndom) { + seed= time(&timedata); + sprintf(seedbuf, " t%d", seed); + strncat(command, seedbuf, sizeof(command)); + } /* else, seed explicitly set to n */ + qh_RANDOMseed_(seed); + + /* ============= explicit points =============== */ + if ((s= first_point)) { + while (s && *s) { /* 'P' */ + count= 0; + if (iscdd) + out1( 1.0); + while (*++s) { + 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--; ) + 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= 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) + out1( 1.0); + for (k=0; k<dim; k++) + 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) + out1( 1.0); + for (k=0; k < dim; k++) + out1( coord[k] * box); + qh_fprintf_rbox(rbox.fout, 9396, "\n"); + } + isregular= 0; /* continue with isbox */ + numpoints= 0; + } + + /* ============= mesh distribution =============== */ + if (ismesh) { + nthroot= pow(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) + out1( mult[0] * meshn + mult[1] * (-meshm)); + else if (k == 1) + out1( mult[0] * meshm + mult[1] * meshn); + else + 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) + out1( 1.0); + out3n( 0.0, 0.0, -box); + if (!isgap) { + if (iscdd) + out1( 1.0); + 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) + out1( 1.0); + out2n( x*box, y*box); + }else { + norm= sqrt(1.0 + x*x + y*y); + if (iscdd) + out1( 1.0); + 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) + out1( 1.0); + 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) + out1( 1.0); + out2n( x*box, y*box); + if (i != 0 && i != numpoints - 1) { + if (iscdd) + out1( 1.0); + 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) + out1( 1.0); + out3n( box*x, box*y, 0); + x *= 1-gap; + y *= 1-gap; + if (iscdd) + out1( 1.0); + out3n( box*x, box*y, box * offset); + if (iscdd) + out1( 1.0); + out3n( box*x, box*y, -box * offset); + } + } + /* ============= apex of 'Zn' distribution + gendim =============== */ + else { + if (isaxis) { + gendim= dim-1; + if (iscdd) + out1( 1.0); + for (j=0; j < gendim; j++) + out1( 0.0); + 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"); + longjmp(rbox.errexit,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) + out1( 1.0); + for (k=0; k < dim; k++) + out1( coord[k] * box); + qh_fprintf_rbox(rbox.fout, 9399, "\n"); + } + } + + /* ============= write cube vertices =============== */ + if (addcube) { + for (j=0; j<cubesize; j++) { + if (iscdd) + out1( 1.0); + for (k=dim-1; k>=0; k--) { + if (j & ( 1 << k)) + out1( cube); + else + out1( -cube); + } + qh_fprintf_rbox(rbox.fout, 9400, "\n"); + } + } + + /* ============= write diamond vertices =============== */ + if (adddiamond) { + for (j=0; j<diamondsize; j++) { + if (iscdd) + out1( 1.0); + for (k=dim-1; k>=0; k--) { + if (j/2 != k) + out1( 0.0); + else if (j & 0x1) + out1( diamond); + else + 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 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 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 a + 0.5; + } +} /* roundi */ + +void out1(double a) { + + if (rbox.isinteger) + qh_fprintf_rbox(rbox.fout, 9403, "%d ", roundi( a+rbox.out_offset)); + else + qh_fprintf_rbox(rbox.fout, 9404, qh_REAL_1, a+rbox.out_offset); +} /* out1 */ + +void out2n( double a, double b) { + + if (rbox.isinteger) + qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", roundi(a+rbox.out_offset), roundi(b+rbox.out_offset)); + else + qh_fprintf_rbox(rbox.fout, 9406, qh_REAL_2n, a+rbox.out_offset, b+rbox.out_offset); +} /* out2n */ + +void out3n( double a, double b, double c) { + + if (rbox.isinteger) + qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", roundi(a+rbox.out_offset), roundi(b+rbox.out_offset), 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); +} /* out3n */ + +void qh_errexit_rbox(int exitcode) +{ + longjmp(rbox.errexit, exitcode); +} /* rbox_errexit */ + diff --git a/src/stat.c b/src/stat.c index 3a1aa05..9a51463 100644 --- a/src/stat.c +++ b/src/stat.c @@ -6,7 +6,9 @@ see qh-stat.htm and stat.h - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/stat.c#22 $$Change: 1059 $ + $DateTime: 2009/10/30 18:26:26 $$Author: bbarber $ */ #include "qhull_a.h" @@ -31,19 +33,19 @@ qhstatT qh_qhstat; /* add "={0}" if this causes a compiler error */ (otherwise, 'gcc -O2' uses too much memory) uses qhstat.next */ -void qh_allstatA (void) { +void qh_allstatA(void) { /* zdef_(type,name,doc,average) */ zzdef_(zdoc, Zdoc2, "precision statistics", -1); zdef_(zinc, Znewvertex, NULL, -1); - zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet (not 0s)", Znewvertex); + 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_(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); @@ -55,7 +57,7 @@ void qh_allstatA (void) { zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1); zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1); } -void qh_allstatB (void) { +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); @@ -75,17 +77,17 @@ void qh_allstatB (void) { 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_(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, 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) { +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); @@ -99,26 +101,31 @@ void qh_allstatC (void) { 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_(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, Zdetsimplex, "determinants computed(area & initial hull)", -1); zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1); - zdef_(zinc, Znotmax, "points ignored (not above max_outside)", -1); - zdef_(zinc, Znotgood, "points ignored (not above a good facet)", -1); - zdef_(zinc, Znotgoodnew, "points ignored (didn't create a good new facet)", -1); + zdef_(zinc, 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); - zdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -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_(zdoc, Zdoc4, "partitioning statistics (see previous for outer planes)", -1); + 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); @@ -162,7 +169,7 @@ 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, 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); @@ -186,8 +193,8 @@ void qh_allstatF(void) { 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_(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); @@ -251,7 +258,7 @@ void qh_allstatH(void) { 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_(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); @@ -274,13 +281,13 @@ void qh_allstatI(void) { zzdef_(wadd, Wridge0, " ave. angle to ridge", Zridge0); zzdef_(wmax, Wridge0max, " max. angle to ridge", -1); - zdef_(zdoc, Zdoc12, "Triangulation statistics (Qt)", -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_(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); + 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" @@ -289,10 +296,10 @@ void qh_allstatI(void) { qh_allstatistics() reset printed flag for all statistics */ -void qh_allstatistics (void) { +void qh_allstatistics(void) { int i; - for (i=ZEND; i--; ) + for(i=ZEND; i--; ) qhstat printed[i]= False; } /* allstatistics */ @@ -304,7 +311,7 @@ void qh_allstatistics (void) { collect statistics for qh.facet_list */ -void qh_collectstatistics (void) { +void qh_collectstatistics(void) { facetT *facet, *neighbor, **neighborp; vertexT *vertex, **vertexp; realT dotproduct, dist; @@ -313,7 +320,7 @@ void qh_collectstatistics (void) { qh old_randomdist= qh RANDOMdist; qh RANDOMdist= False; zval_(Zmempoints)= qh num_points * qh normal_size + - sizeof (qhT) + sizeof (qhstatT); + sizeof(qhT) + sizeof(qhstatT); zval_(Zmemfacets)= 0; zval_(Zmemridges)= 0; zval_(Zmemvertices)= 0; @@ -326,7 +333,7 @@ void qh_collectstatistics (void) { zval_(Znumvneighbors)= 0; zval_(Znummergetot)= 0; zval_(Znummergemax)= 0; - zval_(Zvertices)= qh num_vertices - qh_setsize (qh del_vertices); + 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) @@ -342,9 +349,9 @@ void qh_collectstatistics (void) { FORALLfacets { if (facet->visible && qh NEWfacets) continue; - sizvertices= qh_setsize (facet->vertices); - sizneighbors= qh_setsize (facet->neighbors); - sizridges= qh_setsize (facet->ridges); + sizvertices= qh_setsize(facet->vertices); + sizneighbors= qh_setsize(facet->neighbors); + sizridges= qh_setsize(facet->ridges); zinc_(Znumfacets); zadd_(Znumvertices, sizvertices); zmax_(Zmaxvertices, sizvertices); @@ -364,17 +371,17 @@ void qh_collectstatistics (void) { zadd_(Znumridges, sizridges); zmax_(Zmaxridges, sizridges); } - zadd_(Zmemfacets, sizeof (facetT) + qh normal_size + 2*sizeof (setT) + 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); + 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)); + zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(facet->outsideset)); if (facet->coplanarset) - zadd_(Zmempoints, sizeof (setT) + SETelemsize * qh_setsize (facet->coplanarset)); + zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(facet->coplanarset)); if (facet->seen) /* Delaunay upper envelope */ continue; facet->seen= True; @@ -400,12 +407,12 @@ void qh_collectstatistics (void) { FORALLvertices { if (vertex->deleted) continue; - zadd_(Zmemvertices, sizeof (vertexT)); + zadd_(Zmemvertices, sizeof(vertexT)); if (vertex->neighbors) { - sizneighbors= qh_setsize (vertex->neighbors); + sizneighbors= qh_setsize(vertex->neighbors); zadd_(Znumvneighbors, sizneighbors); zmax_(Zmaxvneighbors, sizneighbors); - zadd_(Zmemvertices, sizeof (vertexT) + SETelemsize * sizneighbors); + zadd_(Zmemvertices, sizeof(vertexT) + SETelemsize * sizneighbors); } } qh RANDOMdist= qh old_randomdist; @@ -418,10 +425,10 @@ void qh_collectstatistics (void) { qh_freestatistics( ) free memory used for statistics */ -void qh_freestatistics (void) { +void qh_freestatistics(void) { #if qh_QHpointer - free (qh_qhstat); + qh_free(qh_qhstat); qh_qhstat= NULL; #endif } /* freestatistics */ @@ -433,17 +440,22 @@ void qh_freestatistics (void) { allocate and initialize statistics notes: - uses malloc() instead of qh_memalloc() since mem.c not set up yet + uses qh_malloc() instead of qh_memalloc() since mem.c not set up yet + NOerrors -- qh_initstatistics can not use qh_errexit(). One first call, qh_memalloc is not initialized. Also invoked by QhullQh(). */ -void qh_initstatistics (void) { +void qh_initstatistics(void) { int i; realT realx; int intx; #if qh_QHpointer - if (!(qh_qhstat= (qhstatT *)malloc (sizeof(qhstatT)))) { - fprintf (qhmem.ferr, "qhull error (qh_initstatistics): insufficient memory\n"); - exit (1); /* can not use qh_errexit() */ + if(qh_qhstat){ /* qh_initstatistics may be called from Qhull::resetStatistics() */ + qh_free(qh_qhstat); + qh_qhstat= 0; + } + if (!(qh_qhstat= (qhstatT *)qh_malloc(sizeof(qhstatT)))) { + qh_fprintf(qhmem.ferr, 6183, "qhull error (qh_initstatistics): insufficient memory\n"); + qh_exit(qh_ERRmem); /* can not use qh_errexit() */ } #endif @@ -459,20 +471,20 @@ void qh_initstatistics (void) { qh_allstatH(); qh_allstatI(); if (qhstat next > sizeof(qhstat id)) { - fprintf (qhmem.ferr, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\ + 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, sizeof(qhstat id)); #if 0 /* for locating error, Znumridges should be duplicated */ - for (i=0; i < ZEND; i++) { + for(i=0; i < ZEND; i++) { int j; - for (j=i+1; j < ZEND; j++) { + for(j=i+1; j < ZEND; j++) { if (qhstat id[i] == qhstat id[j]) { - fprintf (qhmem.ferr, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n", + qh_fprintf(qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n", qhstat id[i], i, j); } } } #endif - exit (1); /* can not use qh_errexit() */ + qh_exit(qh_ERRqhull); /* can not use qh_errexit() */ } qhstat init[zinc].i= 0; qhstat init[zadd].i= 0; @@ -481,7 +493,7 @@ void qh_initstatistics (void) { qhstat init[wadd].r= 0; qhstat init[wmin].r= REALmax; qhstat init[wmax].r= -REALmax; - for (i=0; i < ZEND; i++) { + 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; @@ -501,7 +513,7 @@ void qh_initstatistics (void) { returns: next zdoc */ -boolT qh_newstats (int index, int *nextindex) { +boolT qh_newstats(int index, int *nextindex) { boolT isnew= False; int start, i; @@ -509,7 +521,7 @@ boolT qh_newstats (int index, int *nextindex) { start= index+1; else start= index; - for (i= start; i < qhstat next && qhstat type[qhstat id[i]] != zdoc; i++) { + 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; } @@ -523,7 +535,7 @@ boolT qh_newstats (int index, int *nextindex) { qh_nostatistic( index ) true if no statistic to print */ -boolT qh_nostatistic (int i) { +boolT qh_nostatistic(int i) { if ((qhstat type[i] > ZTYPEreal &&qhstat stats[i].r == qhstat init[(unsigned char)(qhstat type[i])].r) @@ -540,12 +552,12 @@ boolT qh_nostatistic (int i) { qh_printallstatistics( fp, string ) print all statistics with header 'string' */ -void qh_printallstatistics (FILE *fp, char *string) { +void qh_printallstatistics(FILE *fp, char *string) { qh_allstatistics(); qh_collectstatistics(); - qh_printstatistics (fp, string); - qh_memstatistics (fp); + qh_printstatistics(fp, string); + qh_memstatistics(fp); } @@ -559,7 +571,7 @@ void qh_printallstatistics (FILE *fp, char *string) { see: qh_printallstatistics() */ -void qh_printstatistics (FILE *fp, char *string) { +void qh_printstatistics(FILE *fp, char *string) { int i, k; realT ave; @@ -567,17 +579,17 @@ void qh_printstatistics (FILE *fp, char *string) { wval_(Wpbalance)= 0; wval_(Wpbalance2)= 0; }else - wval_(Wpbalance2)= qh_stddev (zval_(Zpbalance), wval_(Wpbalance), + wval_(Wpbalance2)= qh_stddev(zval_(Zpbalance), wval_(Wpbalance), wval_(Wpbalance2), &ave); - wval_(Wnewbalance2)= qh_stddev (zval_(Zprocessed), wval_(Wnewbalance), + wval_(Wnewbalance2)= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance), wval_(Wnewbalance2), &ave); - fprintf (fp, "\n\ + 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); - fprintf (fp, "\nprecision constants:\n\ - %6.2g max. abs. coordinate in the (transformed) input ('Qbd:n')\n\ - %6.2g max. roundoff error for distance computation ('En')\n\ + 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\ @@ -587,26 +599,26 @@ void qh_printstatistics (FILE *fp, char *string) { qh MAXabs_coord, qh DISTround, qh ANGLEround, qh MINoutside, qh MINvisible, qh MAXcoplanar, qh WIDEfacet); if (qh KEEPnearinside) - fprintf(fp, "\ + qh_fprintf(fp, 9352, "\ %6.2g max. distance for near-inside points\n", qh NEARinside); - if (qh premerge_cos < REALmax/2) fprintf (fp, "\ + 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) fprintf (fp, "\ + if (qh PREmerge) qh_fprintf(fp, 9354, "\ %6.2g radius of pre-merge centrum\n", qh premerge_centrum); - if (qh postmerge_cos < REALmax/2) fprintf (fp, "\ + 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) fprintf (fp, "\ + if (qh POSTmerge) qh_fprintf(fp, 9356, "\ %6.2g radius of post-merge centrum\n", qh postmerge_centrum); - fprintf (fp, "\ + 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++) - fprintf (fp, "%6.2e ", qh NEARzero[k]); - fprintf (fp, "\n\n"); - for (i=0 ; i < qhstat next; ) - qh_printstats (fp, i, &i); + 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 */ @@ -619,13 +631,13 @@ void qh_printstatistics (FILE *fp, char *string) { 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) { #define NULLfield " " if (id >= ZEND || qhstat printed[id]) return; if (qhstat type[id] == zdoc) { - fprintf (fp, "%s\n", qhstat doc[id]); + qh_fprintf(fp, 9360, "%s\n", qhstat doc[id]); return; } start= 0; /* not used */ @@ -634,16 +646,16 @@ void qh_printstatlevel (FILE *fp, int id, int start) { qhstat printed[id]= True; if (qhstat count[id] != -1 && qhstat stats[(unsigned char)(qhstat count[id])].i == 0) - fprintf (fp, " *0 cnt*"); + qh_fprintf(fp, 9361, " *0 cnt*"); else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] == -1) - fprintf (fp, "%7.2g", qhstat stats[id].r); + qh_fprintf(fp, 9362, "%7.2g", qhstat stats[id].r); else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] != -1) - fprintf (fp, "%7.2g", qhstat stats[id].r/ qhstat stats[(unsigned char)(qhstat count[id])].i); + 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) - fprintf (fp, "%7d", qhstat stats[id].i); + qh_fprintf(fp, 9364, "%7d", qhstat stats[id].i); else if (qhstat type[id] < ZTYPEreal && qhstat count[id] != -1) - fprintf (fp, "%7.3g", (realT) qhstat stats[id].i / qhstat stats[(unsigned char)(qhstat count[id])].i); - fprintf (fp, " %s\n", qhstat doc[id]); + 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 */ @@ -656,13 +668,13 @@ void qh_printstatlevel (FILE *fp, int id, int start) { returns: next zdoc if non-null */ -void qh_printstats (FILE *fp, int index, int *nextindex) { +void qh_printstats(FILE *fp, int index, int *nextindex) { int j, nexti; - if (qh_newstats (index, &nexti)) { - fprintf (fp, "\n"); + if (qh_newstats(index, &nexti)) { + qh_fprintf(fp, 9367, "\n"); for (j=index; j<nexti; j++) - qh_printstatlevel (fp, qhstat id[j], 0); + qh_printstatlevel(fp, qhstat id[j], 0); } if (nextindex) *nextindex= nexti; @@ -684,19 +696,19 @@ void qh_printstats (FILE *fp, int index, int *nextindex) { == tot2 - 2 tot tot/num + tot tot/num == tot2 - tot ave */ -realT qh_stddev (int num, realT tot, realT tot2, realT *ave) { +realT qh_stddev(int num, realT tot, realT tot2, realT *ave) { realT stddev; *ave= tot/num; - stddev= sqrt (tot2/num - *ave * *ave); + 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) {} +void qh_collectstatistics(void) {} +void qh_printallstatistics(FILE *fp, char *string) {}; +void qh_printstatistics(FILE *fp, char *string) {} #endif diff --git a/src/stat.h b/src/stat.h index 96c4e60..1e0eeb6 100644 --- a/src/stat.h +++ b/src/stat.h @@ -1,4 +1,4 @@ - /*<html><pre> -<a href="qh-stat.htm" +/*<html><pre> -<a href="qh-stat.htm" >-------------------------------</a><a name="TOP">-</a> stat.h @@ -6,7 +6,9 @@ see qh-stat.htm and stat.c - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/stat.h#21 $$Change: 1099 $ + $DateTime: 2009/12/04 22:49:19 $$Author: bbarber $ recompile qhull if you change this file @@ -19,6 +21,7 @@ #ifndef qhDEFstat #define qhDEFstat 1 +#include "qhulllib.h" /*-<a href="qh-stat.htm#TOC" >-------------------------------</a><a name="KEEPstatistics">-</a> @@ -262,8 +265,12 @@ enum statistics { /* alphabetical after Z/W */ Zvertices, Zvisfacettot, Zvisfacetmax, + Zvisit, + Zvisit2max, Zvisvertextot, Zvisvertexmax, + Zvvisit, + Zvvisit2max, Zwidefacet, Zwidevertices, ZEND}; @@ -321,6 +328,7 @@ enum statistics { /* for zzdef etc. macros */ Wridgeok, Wridgeokmax, Zsetplane, + Ztotcheck, Ztotmerge, ZEND}; #endif @@ -458,7 +466,7 @@ union intrealT { >--------------------------------</a><a name="qhstat">-</a> qhstat - global data structure for statistics + global data structure for statistics, similar to qh and qhrbox notes: access to qh_qhstat is via the "qhstat" macro. There are two choices @@ -467,11 +475,15 @@ union intrealT { = 0 qh_qhstat is a static data structure only one instance of qhull() can be active at a time default value - qh_QHpointer is defined in qhull.h + qh_QHpointer is defined in qhulllib.h - allocated in stat.c + allocated in stat.c using qh_malloc() */ +#ifndef DEFqhstatT +#define DEFqhstatT 1 typedef struct qhstatT qhstatT; +#endif + #if qh_QHpointer #define qhstat qh_qhstat-> extern qhstatT *qh_qhstat; @@ -507,16 +519,16 @@ void qh_allstatF(void); void qh_allstatG(void); void qh_allstatH(void); void qh_allstatI(void); -void qh_allstatistics (void); -void qh_collectstatistics (void); -void qh_freestatistics (void); -void qh_initstatistics (void); -boolT qh_newstats (int index, int *nextindex); -boolT qh_nostatistic (int i); -void qh_printallstatistics (FILE *fp, char *string); -void qh_printstatistics (FILE *fp, char *string); -void qh_printstatlevel (FILE *fp, int id, int start); -void qh_printstats (FILE *fp, int index, int *nextindex); -realT qh_stddev (int num, realT tot, realT tot2, realT *ave); +void qh_allstatistics(void); +void qh_collectstatistics(void); +void qh_freestatistics(void); +void qh_initstatistics(void); +boolT qh_newstats(int index, int *nextindex); +boolT qh_nostatistic(int i); +void qh_printallstatistics(FILE *fp, char *string); +void qh_printstatistics(FILE *fp, char *string); +void qh_printstatlevel(FILE *fp, int id, int start); +void qh_printstats(FILE *fp, int index, int *nextindex); +realT qh_stddev(int num, realT tot, realT tot2, realT *ave); #endif /* qhDEFstat */ diff --git a/src/unix.c b/src/unix.c index 9f06fce..898f98e 100644 --- a/src/unix.c +++ b/src/unix.c @@ -7,17 +7,20 @@ see qh-qhull.htm - copyright (c) 1993-2003, The Geometry Center + copyright (c) 1993-2009 The Geometry Center. + $Id: //product/qhull/main/rel/src/unix.c#23 $$Change: 1096 $ + $DateTime: 2009/12/04 21:52:01 $$Author: bbarber $ */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <math.h> -#include "qhull.h" #include "mem.h" #include "qset.h" +#include "qhulllib.h" + +#include <ctype.h> +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> #if __MWERKS__ && __POWERPC__ #include <SIOUX.h> @@ -27,7 +30,7 @@ #elif __cplusplus extern "C" { - int isatty (int); + int isatty(int); } #elif _MSC_VER @@ -35,7 +38,7 @@ extern "C" { #define isatty _isatty #else -int isatty (int); /* returns 1 if stdin is a tty +int isatty(int); /* returns 1 if stdin is a tty if "Undefined symbol" this can be deleted along with call in main() */ #endif @@ -109,6 +112,7 @@ char qh_promptb[]= "\ 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\ @@ -171,7 +175,7 @@ More formats:\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\ + #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\ @@ -231,7 +235,7 @@ options (qh-quick.htm):\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\ + - - one-line description of each option\n\ \n\ Output options (subset):\n\ s - summary of results (default)\n\ @@ -295,9 +299,9 @@ Except for 'F.' and 'PG', upper-case options take an argument.\n\ Q5_no_check_out Q6_no_concave Q7_depth_first Q8_no_near_in Q9_pick_furthest\n\ Q10_no_narrow Q11_trinormals\n\ \n\ - T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\ - TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\ - TRerun TWide_trace TVertex_stop TCone_stop\n\ + 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\ @@ -329,10 +333,10 @@ int main(int argc, char *argv[]) { 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"); + 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 @@ -349,12 +353,12 @@ int main(int argc, char *argv[]) { 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(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_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(); @@ -367,9 +371,9 @@ int main(int argc, char *argv[]) { qh_freeqhull( True); #else qh_freeqhull( False); - qh_memfreeshort (&curlong, &totlong); + qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) - fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", + fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); #endif return exitcode; diff --git a/src/user.c b/src/user.c index b9a75a0..fc6d7af 100644 --- a/src/user.c +++ b/src/user.c @@ -4,9 +4,11 @@ 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 qhull.h for data structures, macros, and user-callable functions. + see qhulllib.h for data structures, macros, and user-callable functions. see user_eg.c, unix.c, and qhull_interface.cpp for examples. @@ -40,6 +42,8 @@ #include "qhull_a.h" +#include <stdarg.h> + /*-<a href="qh-user.htm#TOC" >-------------------------------</a><a name="call_qhull">-</a> @@ -48,7 +52,7 @@ remove #if 0, #endif to compile returns: - exit code (see qh_ERR... in qhull.h) + exit code(see qh_ERR... in qhulllib.h) all memory freed notes: @@ -73,7 +77,7 @@ int curlong, totlong; /* memory remaining after qh_memfreeshort */ /* initialize dim, numpoints, points[], ismalloc here */ - exitcode= qh_new_qhull (dim, numpoints, points, ismalloc, + exitcode= qh_new_qhull(dim, numpoints, points, ismalloc, flags, outfile, errfile); if (!exitcode) { /* if no error */ /* 'qh facet_list' contains the convex hull */ @@ -82,9 +86,9 @@ } } qh_freeqhull(!qh_ALL); - qh_memfreeshort (&curlong, &totlong); + 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); + qh_fprintf(errfile, 7068, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); } #endif @@ -114,7 +118,7 @@ see: user_eg.c for an example */ -int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, +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; @@ -122,37 +126,37 @@ int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, coordT *new_points; if (firstcall) { - qh_meminit (errfile); + qh_meminit(errfile); firstcall= False; } - if (strncmp (qhull_cmd,"qhull ", 6)) { - fprintf (errfile, "qh_new_qhull: start qhull_cmd argument with \"qhull \"\n"); - exit(1); + if (strncmp(qhull_cmd,"qhull ", 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); - trace1(( qh ferr, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd)); - exitcode = setjmp (qh errexit); + qh_initqhull_start(NULL, outfile, errfile); + 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); + 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); + qh_setfeasible(hulldim); + new_points= qh_sethalfspace_all(dim, numpoints, points, qh feasible_point); new_ismalloc= True; if (ismalloc) - free (points); + qh_free(points); }else { hulldim= dim; new_points= points; new_ismalloc= ismalloc; } - qh_init_B (new_points, numpoints, hulldim, new_ismalloc); + qh_init_B(new_points, numpoints, hulldim, new_ismalloc); qh_qhull(); qh_check_output(); if (outfile) @@ -174,7 +178,7 @@ int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, set qh.FORCEoutput to print neighborhood of facet see: - qh_errexit2() in qhull.c for printing 2 facets + qh_errexit2() in qhulllib.c for printing 2 facets design: check for error within error processing @@ -189,50 +193,51 @@ int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) { if (qh ERREXITcalled) { - fprintf (qh ferr, "\nqhull error while processing previous error. Exit program\n"); - exit(1); + qh_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); - fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command); - fprintf(qh ferr, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options); + 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) { - fprintf(qh ferr, "Last point added to hull was p%d.", qh furthest_id); + qh_fprintf(qh ferr, 8129, "Last point added to hull was p%d.", qh furthest_id); if (zzval_(Ztotmerge)) - fprintf(qh ferr, " Last merge was #%d.", zzval_(Ztotmerge)); + qh_fprintf(qh ferr, 8130, " Last merge was #%d.", zzval_(Ztotmerge)); if (qh QHULLfinished) - fprintf(qh ferr, "\nQhull has finished constructing the hull."); + qh_fprintf(qh ferr, 8131, "\nQhull has finished constructing the hull."); else if (qh POSTmerging) - fprintf(qh ferr, "\nQhull has started post-merging."); - fprintf (qh ferr, "\n"); + 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_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) { - fprintf (qh ferr, "\nAt error exit:\n"); - qh_printsummary (qh ferr); + 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); + qh_memstatistics(qh ferr); } } if (qh PRINTprecision) - qh_printstats (qh ferr, qhstat precision, NULL); + 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); + qh_printhelp_degenerate(qh ferr); if (qh NOerrexit) { - fprintf (qh ferr, "qhull error while ending program. Exit program\n"); - exit(1); + qh_fprintf(qh ferr, 6187, "qhull error while ending program. Exit program\n"); + qh_exit(qh_ERRqhull); } + qh ERREXITcalled= False; qh NOerrexit= True; longjmp(qh errexit, exitcode); } /* errexit */ @@ -252,15 +257,15 @@ void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atri int i; if (atfacet) { - fprintf(qh ferr, "%s FACET:\n", string); + qh_fprintf(qh ferr, 8135, "%s FACET:\n", string); qh_printfacet(qh ferr, atfacet); } if (otherfacet) { - fprintf(qh ferr, "%s OTHER FACET:\n", string); + qh_fprintf(qh ferr, 8136, "%s OTHER FACET:\n", string); qh_printfacet(qh ferr, otherfacet); } if (atridge) { - fprintf(qh ferr, "%s RIDGE:\n", string); + 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); @@ -273,13 +278,13 @@ void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atri otherfacet= otherfacet_(atridge, atfacet); } if (atvertex) { - fprintf(qh ferr, "%s VERTEX:\n", string); - qh_printvertex (qh ferr, 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) { - fprintf(qh ferr, "ERRONEOUS and NEIGHBORING FACETS to output\n"); - for (i= 0; i < qh_PRINTEND; i++) /* use fout for geomview output */ - qh_printneighborhood (qh fout, qh PRINTout[i], atfacet, otherfacet, + qh_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 */ @@ -299,15 +304,204 @@ void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atri void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) { facetT *facet, **facetp; - qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall); + 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); + 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\ +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 */ + +/*-<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_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 qhulllib.h).\n"); +#endif + qh_fprintf(fp, 9389, "\n\ +If the input is lower dimensional:\n\ + - use 'QJ' to joggle the input and make it full dimensional\n\ + - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\ + pick the coordinate with the least range. The hull will have the\n\ + correct topology.\n\ + - determine the flat containing the points, rotate the points\n\ + into a coordinate plane, and delete the other coordinates.\n\ + - add one or more points to make the input full dimensional.\n\ +"); + if (qh DELAUNAY && !qh ATinfinity) + qh_fprintf(fp, 9390, "\n\n\ +This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\ + - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\ + - or use 'QJ' to joggle the input and avoid co-circular data\n"); + } +} /* printhelp_singular */ + /*-<a href="qh-globa.htm#TOC" >-------------------------------</a><a name="user_memsizes">-</a> @@ -317,8 +511,9 @@ void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) { notes: increase maximum number of allocations in qh_initqhull_mem() */ -void qh_user_memsizes (void) { +void qh_user_memsizes(void) { - /* qh_memsize (size); */ + /* qh_memsize(size); */ } /* user_memsizes */ + diff --git a/src/user.h b/src/user.h index 7955896..e19d59e 100644 --- a/src/user.h +++ b/src/user.h @@ -6,14 +6,75 @@ see qh-user.htm. see COPYING for copyright information. - before reading any code, review qhull.h for data structure definitions and + before reading any code, review qhulllib.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 maybe incompatible with 64-bit pointers + */ #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. + + def counters = [27, 1047, 2059, 3025, 4068, 5003, 6231, 7078, 8143, 9410] + + See: qh_ERR* [qhulllib.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_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> @@ -38,7 +99,7 @@ or double precision (double). Use 'float' to save about 8% in time and 25% in space. This is particularly - help if high-d where convex hulls are space limited. Using 'float' also + 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. @@ -105,8 +166,8 @@ 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. - + to 'unsigned long' to prevent wrap-around during long runs. By default, + <time.h> defines clock_t as 'long' Set qh_CLOCKtype to @@ -119,15 +180,15 @@ #if (qh_CLOCKtype == 1) -#if defined (CLOCKS_PER_SECOND) +#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) +#elif defined(CLOCKS_PER_SEC) #define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */ #define qh_SECticks CLOCKS_PER_SEC -#elif defined (CLK_TCK) +#elif defined(CLK_TCK) #define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */ #define qh_SECticks CLK_TCK @@ -221,7 +282,85 @@ #define qh_ORIENTclock 0 -/*========= performance related constants =========*/ +/*============================================================*/ +/*============= 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> @@ -265,79 +404,9 @@ */ #define qh_INITIALmax 8 -/*-<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 - -/*========= memory constants =========*/ +/*============================================================*/ +/*============= memory constants =============================*/ +/*============================================================*/ /*-<a href="qh-user.htm#TOC" >--------------------------------</a><a name="MEMalign">-</a> @@ -395,10 +464,16 @@ 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 ============================*/ +/*============================================================*/ +/*============= conditional compilation ======================*/ +/*============================================================*/ /*-<a href="qh-user.htm#TOC" >--------------------------------</a><a name="compiler">-</a> @@ -502,32 +577,35 @@ notes: all global variables for qhull are in qh, qhmem, and qhstat - qh is defined in qhull.h + qh is defined in qhulllib.h qhmem is defined in mem.h qhstat is defined in stat.h see: user_eg.c for an example + FIXUP need to override for C++ (-Dqh_QHpointer=1) */ -#define qh_QHpointer 0 +#ifndef qh_QHpointer +#define qh_QHpointer 1 +#endif #if 0 /* sample code */ qhT *oldqhA, *oldqhB; - exitcode= qh_new_qhull (dim, numpoints, points, ismalloc, + 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, + 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); + 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); + 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 */ + 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" @@ -538,10 +616,12 @@ */ #define qh_QUICKhelp 0 -/* ============ -merge constants- ==================== - +/*============================================================*/ +/*============= -merge constants- ============================*/ +/*============================================================*/ +/* These constants effect facet merging. You probably will not need - to modify these. They effect the performance of facet merging. + to modify them. They effect the performance of facet merging. */ /*-<a href="qh-user.htm#TOC" diff --git a/src/user_eg.c b/src/user_eg.c index 9f2ac81..080acc8 100644 --- a/src/user_eg.c +++ b/src/user_eg.c @@ -3,7 +3,7 @@ user_eg.c sample code for calling qhull() from an application - + call with: user_eg "cube/diamond options" "delaunay options" "halfspace options" @@ -31,7 +31,7 @@ 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. @@ -42,7 +42,7 @@ compiled by 'make user_eg' - see qhull.h for data structures, macros, and user-callable functions. + see qhulllib.h for data structures, macros, and user-callable functions. */ #include "qhull_a.h" @@ -63,10 +63,10 @@ void print_summary (void) { facetT *facet; int k; - printf ("\n%d vertices and %d facets with normals:\n", + printf ("\n%d vertices and %d facets with normals:\n", qh num_vertices, qh num_facets); FORALLfacets { - for (k=0; k < qh hull_dim; k++) + for (k=0; k < qh hull_dim; k++) printf ("%6.2g ", facet->normal[k]); printf ("\n"); } @@ -119,7 +119,7 @@ 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-in.htm#findfacet">locate a facet with qh_findbestfacet()</a> + See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a> */ void findDelaunay (int dim) { int k; @@ -129,7 +129,7 @@ void findDelaunay (int dim) { facetT *facet; vertexT *vertex, **vertexp; - for (k= 0; k < dim; k++) + for (k= 0; k < dim; k++) point[k]= 0.5; qh_setdelaunay (dim+1, 1, point); facet= qh_findbestfacet (point, qh_ALL, &bestdist, &isoutside); @@ -212,7 +212,7 @@ your project.\n\n"); rows[i]= points+dim*i; qh_printmatrix (outfile, "input", rows, numpoints, dim); exitcode= qh_new_qhull (dim, numpoints, points, ismalloc, - flags, outfile, errfile); + flags, outfile, errfile); if (!exitcode) { /* if no error */ /* 'qh facet_list' contains the convex hull */ print_summary(); @@ -222,7 +222,7 @@ your project.\n\n"); } qh_freeqhull(!qh_ALL); /* free long memory */ qh_memfreeshort (&curlong, &totlong); /* free short memory and memory allocator */ - if (curlong || totlong) + if (curlong || totlong) fprintf (errfile, "qhull internal warning (user_eg, #1): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong); /* @@ -232,22 +232,22 @@ your project.\n\n"); 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, time(NULL)); + makeDelaunay (points, numpoints, dim, (int)time(NULL)); for (i=numpoints; i--; ) rows[i]= points+dim*i; qh_printmatrix (outfile, "input", rows, numpoints, dim); exitcode= qh_new_qhull (dim, numpoints, points, ismalloc, - flags, outfile, errfile); + flags, outfile, errfile); if (!exitcode) { /* if no error */ /* 'qh facet_list' contains the convex hull */ - /* If you want a Voronoi diagram ('v') and do not request output (i.e., outfile=NULL), + /* If you want a Voronoi diagram ('v') and do not request output (i.e., outfile=NULL), call qh_setvoronoi_all() after qh_new_qhull(). */ print_summary(); FORALLfacets { /* ... your code ... */ } printf( "\nfind %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim); - exitcode= setjmp (qh errexit); + exitcode= setjmp (qh errexit); if (!exitcode) { /* Trap Qhull errors in findDelaunay(). Without the setjmp(), Qhull will exit() after reporting an error */ @@ -266,12 +266,12 @@ your project.\n\n"); oldqhA= qh_save_qhull(); sprintf (flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : ""); numpoints= SIZEcube; - makeDelaunay (pointsB, numpoints, dim, time(NULL)+1); + makeDelaunay (pointsB, numpoints, dim, (int)time(NULL)+1); for (i=numpoints; i--; ) rows[i]= pointsB+dim*i; qh_printmatrix (outfile, "input", rows, numpoints, dim); exitcode= qh_new_qhull (dim, numpoints, pointsB, ismalloc, - flags, outfile, errfile); + flags, outfile, errfile); if (!exitcode) print_summary(); printf( "\nsave second triangulation and restore first one\n"); @@ -287,7 +287,7 @@ your project.\n\n"); #endif qh_freeqhull(!qh_ALL); /* free long memory */ qh_memfreeshort (&curlong, &totlong); /* free short memory and memory allocator */ - if (curlong || totlong) + if (curlong || totlong) fprintf (errfile, "qhull internal warning (user_eg, #2): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong); /* @@ -300,12 +300,12 @@ your project.\n\n"); for (i=numpoints; i--; ) rows[i]= points+(dim+1)*i; qh_printmatrix (outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1); - /* use qh_sethalfspace_all to transform the halfspaces yourself. + /* use qh_sethalfspace_all to transform the halfspaces yourself. If so, set 'qh feasible_point and do not use option 'Hn,...' [it would retransform the halfspaces] */ exitcode= qh_new_qhull (dim+1, numpoints, points, ismalloc, - flags, outfile, errfile); - if (!exitcode) + flags, outfile, errfile); + if (!exitcode) print_summary(); qh_freeqhull (!qh_ALL); qh_memfreeshort (&curlong, &totlong); diff --git a/src/user_eg2.c b/src/user_eg2.c index 28ecbce..fa2cc47 100644 --- a/src/user_eg2.c +++ b/src/user_eg2.c @@ -7,8 +7,8 @@ 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. - + control over Qhull. + call with: user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options" @@ -34,15 +34,15 @@ 3) compute the halfspace intersection of a diamond, and add a cube notes: - + summaries are sent to stderr if other output formats are used derived from unix.c and compiled by 'make user_eg2' - see qhull.h for data structures, macros, and user-callable functions. - + see qhulllib.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". + 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. @@ -70,10 +70,10 @@ void print_summary (void) { facetT *facet; int k; - printf ("\n%d vertices and %d facets with normals:\n", + printf ("\n%d vertices and %d facets with normals:\n", qh num_vertices, qh num_facets); FORALLfacets { - for (k=0; k < qh hull_dim; k++) + for (k=0; k < qh hull_dim; k++) printf ("%6.2g ", facet->normal[k]); printf ("\n"); } @@ -101,13 +101,13 @@ void makecube (coordT *points, int numpoints, int dim) { /*-------------------------------------------------- -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 + 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) { @@ -123,7 +123,7 @@ void adddiamond (coordT *points, int numpoints, int numnew, int dim) { 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) @@ -136,7 +136,7 @@ void adddiamond (coordT *points, int numpoints, int numnew, int dim) { if (!qh_addpoint (point, facet, False)) break; /* user requested an early exit with 'TVn' or 'TCn' */ } - printf ("%d vertices and %d facets\n", + printf ("%d vertices and %d facets\n", qh num_vertices, qh num_facets); /* qh_produce_output(); */ } @@ -154,7 +154,7 @@ void makeDelaunay (coordT *points, int numpoints, int dim) { int j,k, seed; coordT *point, realr; - seed= time(NULL); + seed= (int)time(NULL); /* time_t to int */ printf ("seed: %d\n", seed); qh_RANDOMseed_( seed); for (j=0; j<numpoints; j++) { @@ -187,10 +187,10 @@ void addDelaunay (coordT *points, int numpoints, int numnew, int dim) { 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; + 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; @@ -203,10 +203,10 @@ void addDelaunay (coordT *points, int numpoints, int numnew, int dim) { break; /* user requested an early exit with 'TVn' or 'TCn' */ } qh_printpoint (stdout, "added point", point); - printf ("%d points, %d extra points, %d vertices, and %d facets in total\n", + 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(); */ } if (qh DOcheckmax) @@ -222,7 +222,7 @@ 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-in.htm#findfacet">locate a facet with qh_findbestfacet()</a> + See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a> */ void findDelaunay (int dim) { int k; @@ -232,7 +232,7 @@ void findDelaunay (int dim) { facetT *facet; vertexT *vertex, **vertexp; - for (k= 0; k < dim-1; k++) + for (k= 0; k < dim-1; k++) point[k]= 0.5; qh_setdelaunay (dim, 1, point); facet= qh_findbestfacet (point, qh_ALL, &bestdist, &isoutside); @@ -274,7 +274,7 @@ void makehalf (coordT *points, int numpoints, int dim) { -addhalf- add halfspaces for a (dim)-d cube to the intersection points is numpoints+numnew X dim+1 notes: - assumes dim < 100. + assumes dim < 100. For makehalf(), points is the initial set of halfspaces with offsets. It is transformed by qh_sethalfspace_all into a @@ -286,7 +286,7 @@ notes: 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, + 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. @@ -299,7 +299,7 @@ void addhalf (coordT *points, int numpoints, int numnew, int dim, coordT *feasib realT bestdist; for (j= 0; j < numnew ; j++) { - offset= -1.0; + offset= -1.0; for (k=dim; k--; ) { if (j/2 == k) { normal[k]= sqrt (dim); /* to normalize as in makehalf */ @@ -316,7 +316,7 @@ void addhalf (coordT *points, int numpoints, int numnew, int dim, coordT *feasib break; /* user requested an early exit with 'TVn' or 'TCn' */ } qh_printpoint (stdout, "added offset -1 and normal", normal); - printf ("%d points, %d extra points, %d vertices, and %d facets in total\n", + 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(); */ @@ -367,14 +367,14 @@ your project.\n\n"); qh_init_B (array[0], SIZEcube, DIM, ismalloc); qh_qhull(); qh_check_output(); - qh_triangulate(); /* requires option 'Q11' if want to add points */ + qh_triangulate(); /* requires option 'Q11' if want to add points */ print_summary (); if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone) qh_check_points (); printf( "\nadd points in a diamond\n"); adddiamond (array[0], SIZEcube, SIZEdiamond, DIM); qh_check_output(); - print_summary (); + print_summary (); qh_produce_output(); /* delete this line to help avoid io.c */ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone) qh_check_points (); @@ -396,8 +396,8 @@ your project.\n\n"); printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1); makeDelaunay (array[0], SIZEcube, DIM); /* Instead of makeDelaunay with qh_setdelaunay, you may - produce a 2-d array of points, set DIM to 2, and set - qh PROJECTdelaunay to True. qh_init_B will call + produce a 2-d array of points, set DIM to 2, and set + qh PROJECTdelaunay to True. qh_init_B will call qh_projectinput to project the points to the paraboloid and add a point "at-infinity". */ @@ -411,7 +411,7 @@ your project.\n\n"); if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone) qh_check_points (); printf( "\nadd points to triangulation\n"); - addDelaunay (array[0], SIZEcube, SIZEdiamond, DIM); + 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) @@ -439,7 +439,7 @@ your project.\n\n"); qh_setfeasible (DIM); /* from io.c, sets qh feasible_point from 'Hn,n' */ /* you may malloc and set qh feasible_point directly. It is only used for option 'Fp' */ - points= qh_sethalfspace_all ( DIM+1, SIZEcube, array[0], qh feasible_point); + 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(); @@ -447,7 +447,7 @@ your project.\n\n"); if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone) qh_check_points (); printf( "\nadd halfspaces for cube to intersection\n"); - addhalf (array[0], SIZEcube, SIZEdiamond, DIM, qh feasible_point); + 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) @@ -468,7 +468,7 @@ your project.\n\n"); -errexit- return exitcode to system after an error assumes exitcode non-zero prints useful information - see qh_errexit2() in qhull.c for 2 facets + see qh_errexit2() in qhulllib.c for 2 facets */ void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) { diff --git a/src/usermem.c b/src/usermem.c new file mode 100644 index 0000000..cdaae05 --- /dev/null +++ b/src/usermem.c @@ -0,0 +1,64 @@ +/*<html><pre> -<a href="qh-user.htm" + >-------------------------------</a><a name="TOP">-</a> + + usermem.c + qh_exit(), qh_free(), and qh_malloc() + + see README.txt see COPYING.txt for copyright information. + + 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 qhulllib.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 qh_fprintf_rbox + + Please report any errors that you fix to qhull@qhull.org +*/ + +#include "qhulllib.h" + +#include <stdlib.h> + +/*-<a href="qh-user.htm#TOC" + >-------------------------------</a><a name="qh_exit">-</a> + + qh_exit( errstatus ) + exit program + + notes: + same as exit() +*/ +void qh_exit(int errstatus) { + exit(errstatus); +} /* exit */ + +/*-<a href="qh-user.htm#TOC" +>-------------------------------</a><a name="qh_free">-</a> + +qh_free( mem ) +free memory + +notes: +same as free() +*/ +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(unsigned int size) { + return malloc(size); +} /* malloc */ + + diff --git a/src/userprintf.c b/src/userprintf.c new file mode 100644 index 0000000..d780b06 --- /dev/null +++ b/src/userprintf.c @@ -0,0 +1,64 @@ +/*<html><pre> -<a href="qh-user.htm" + >-------------------------------</a><a name="TOP">-</a> + + userprintf.c + qh_fprintf() and qh_fprintf_rbox() + + see README.txt see COPYING.txt for copyright information. + + If you redefine one of these functions you must redefine all of them. + If you recompile and load this file, then userprintf.o will not be loaded + from qhull.a or qhull.lib + + See qhulllib.h for data structures, macros, and user-callable functions. + See user.c for qhull-related, redefinable functions + see user.h for user-definable constants + See usermem.c for qh_exit(), qh_free(), and qh_malloc() + see Qhull.cpp and RboxPoints.cpp for examples. + + Please report any errors that you fix to qhull@qhull.org +*/ + +#include "qhulllib.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +/*-<a href="qh-user.htm#TOC" + >-------------------------------</a><a name="qh_fprintf">-</a> + + qh_fprintf(fp, msgcode, format, list of args ) + print arguments to *fp according to format + Use qh_fprintf_rbox() for rboxlib.c + + notes: + same as fprintf() + fgets() is not trapped like fprintf() + exit qh_fprintf via qh_errexit() + exit qh_fprintf_rbox via qh_errexit_rbox() +*/ + +void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) { + va_list args; + + va_start(args, fmt); + if (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); +} /* qh_fprintf */ + +void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) { + va_list args; + + 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/vcproj/qhull.sln b/vcproj/qhull.sln new file mode 100644 index 0000000..aa8bb98 --- /dev/null +++ b/vcproj/qhull.sln @@ -0,0 +1,134 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhull", "qhull.vcproj", "{DEB5D824-712C-47C7-BE7E-E0A866373C26}" + ProjectSection(ProjectDependencies) = postProject + {D1377F6B-7868-460C-9FC5-489C32A3D08F} = {D1377F6B-7868-460C-9FC5-489C32A3D08F} + EndProjectSection + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhulllib", "qhulllib.vcproj", "{D1377F6B-7868-460C-9FC5-489C32A3D08F}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rbox", "rbox.vcproj", "{D137FB9B-7868-460C-9FC5-489C32A3D08F}" + ProjectSection(ProjectDependencies) = postProject + {D1377F6B-7868-460C-9FC5-489C32A3D08F} = {D1377F6B-7868-460C-9FC5-489C32A3D08F} + EndProjectSection + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhullcpp", "qhullcpp.vcproj", "{83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}" + ProjectSection(ProjectDependencies) = postProject + {D1377F6B-7868-460C-9FC5-489C32A3D08F} = {D1377F6B-7868-460C-9FC5-489C32A3D08F} + EndProjectSection + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_eg3", "user_eg3.vcproj", "{B94D6587-1030-4EA0-8322-E9B2902A9AC4}" + ProjectSection(ProjectDependencies) = postProject + {D1377F6B-7868-460C-9FC5-489C32A3D08F} = {D1377F6B-7868-460C-9FC5-489C32A3D08F} + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49} = {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49} + EndProjectSection + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhulltest", "qhulltest.vcproj", "{AFDCA33D-3D74-3866-BAE1-97033FE213AA}" + ProjectSection(ProjectDependencies) = postProject + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49} = {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49} + {D1377F6B-7868-460C-9FC5-489C32A3D08F} = {D1377F6B-7868-460C-9FC5-489C32A3D08F} + EndProjectSection + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Debug|Win32.ActiveCfg = Debug|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Release|Any CPU.ActiveCfg = Release|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Release|Mixed Platforms.Build.0 = Release|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Release|Win32.ActiveCfg = Release|Win32 + {DEB5D824-712C-47C7-BE7E-E0A866373C26}.Release|Win32.Build.0 = Release|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Debug|Win32.ActiveCfg = Debug|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Debug|Win32.Build.0 = Debug|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Release|Any CPU.ActiveCfg = Release|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Release|Mixed Platforms.Build.0 = Release|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Release|Win32.ActiveCfg = Release|Win32 + {D1377F6B-7868-460C-9FC5-489C32A3D08F}.Release|Win32.Build.0 = Release|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Debug|Win32.ActiveCfg = Debug|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Debug|Win32.Build.0 = Debug|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Release|Any CPU.ActiveCfg = Release|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Release|Mixed Platforms.Build.0 = Release|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Release|Win32.ActiveCfg = Release|Win32 + {D137FB9B-7868-460C-9FC5-489C32A3D08F}.Release|Win32.Build.0 = Release|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Debug|Win32.ActiveCfg = Debug|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Debug|Win32.Build.0 = Debug|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Release|Any CPU.ActiveCfg = Release|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Release|Mixed Platforms.Build.0 = Release|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Release|Win32.ActiveCfg = Release|Win32 + {83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}.Release|Win32.Build.0 = Release|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Debug|Win32.ActiveCfg = Debug|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Release|Any CPU.ActiveCfg = Release|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Release|Mixed Platforms.Build.0 = Release|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Release|Win32.ActiveCfg = Release|Win32 + {B94D6587-1030-4EA0-8322-E9B2902A9AC4}.Release|Win32.Build.0 = Release|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Debug|Win32.Build.0 = Debug|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Release|Any CPU.ActiveCfg = Release|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Release|Mixed Platforms.Build.0 = Release|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Release|Win32.ActiveCfg = Release|Win32 + {AFDCA33D-3D74-3866-BAE1-97033FE213AA}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + QtVersion = 4.5.3 + EndGlobalSection + GlobalSection(Qt) = preSolution + Integration = True + EndGlobalSection +EndGlobal diff --git a/vcproj/qhull.vcproj b/vcproj/qhull.vcproj new file mode 100644 index 0000000..ff21035 --- /dev/null +++ b/vcproj/qhull.vcproj @@ -0,0 +1,227 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="qhull" + ProjectGUID="{DEB5D824-712C-47C7-BE7E-E0A866373C26}" + RootNamespace="qhull" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\qhull\Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="../" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;NDEBUG" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\qhull\Release/qhull.pch" + AssemblerListingLocation="..\tmp\qhull\Release/" + ObjectFile="..\tmp\qhull\Release/" + ProgramDataBaseFileName="..\tmp\qhull\Release/" + BrowseInformation="1" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions=""..\tmp\qhulllib\Release\qhull.lib"" + OutputFile="..\qhull.exe" + LinkIncremental="0" + /> + <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="Debug|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\qhull\Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;_DEBUG" + ExceptionHandling="0" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\qhull\Debug/qhull.pch" + AssemblerListingLocation="..\tmp\qhull\Debug/" + ObjectFile="..\tmp\qhull\Debug/" + ProgramDataBaseFileName="..\tmp\qhull\Debug/" + BrowseInformation="1" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions=""..\tmp\qhulllib\Debug\qhull.lib"" + OutputFile="../qhull.exe" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + /> + <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" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + > + <File + RelativePath="..\src\unix.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + <File + RelativePath="..\src\mem.h" + > + </File> + <File + RelativePath="..\src\qhulllib.h" + > + </File> + <File + RelativePath="..\src\qset.h" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vcproj/qhullcpp.vcproj b/vcproj/qhullcpp.vcproj new file mode 100644 index 0000000..f2296ea --- /dev/null +++ b/vcproj/qhullcpp.vcproj @@ -0,0 +1,422 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="qhullcpp" + ProjectGUID="{83B9A40B-EA6E-4DD8-A9D5-D51FFA0B5F49}" + RootNamespace="Qhull" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="..\tmp\qhullcpp\Release" + IntermediateDirectory="..\tmp\qhullcpp\Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TypeLibraryName="..\tmp\qhullcpp\Release/qhullcpp.tlb" + HeaderFileName="" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + PrecompiledHeaderFile="..\tmp\qhullcpp\Release/qhullcpp.pch" + AssemblerListingLocation="..\tmp\qhullcpp\Release/" + ObjectFile="..\tmp\qhullcpp\Release/" + ProgramDataBaseFileName="..\tmp\qhullcpp\Release/" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="..\tmp\qhullcpp\Release\qhullcpp.lib" + SuppressStartupBanner="true" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="..\tmp\qhullcpp\Debug" + IntermediateDirectory="..\tmp\qhullcpp\Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TypeLibraryName="..\tmp\qhullcpp\Debug/qhullcpp.tlb" + HeaderFileName="" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\cpp,..\..\cpp,..\src,..\..\src,..\tmp,..\..\tmp" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + GeneratePreprocessedFile="0" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + DisableLanguageExtensions="true" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\qhullcpp\Debug/qhullcpp.pch" + AssemblerListingLocation="..\tmp\qhullcpp\Debug/" + ObjectFile="..\tmp\qhullcpp\Debug/" + ProgramDataBaseFileName="..\tmp\qhullcpp\Debug/" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="..\tmp\qhullcpp\Debug\qhullcpp.lib" + SuppressStartupBanner="true" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + > + <File + RelativePath="..\cpp\Coordinates.cpp" + > + </File> + <File + RelativePath="..\cpp\PointCoordinates.cpp" + > + </File> + <File + RelativePath="..\cpp\Qhull.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullFacet.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullFacetList.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullFacetSet.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullHyperplane.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullLog.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullPoint.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullPoints.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullPointSet.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullQh.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullRidge.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullSet.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullStat.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullVertex.cpp" + > + </File> + <File + RelativePath="..\cpp\QhullVertexSet.cpp" + > + </File> + <File + RelativePath="..\cpp\RboxPoints.cpp" + > + </File> + <File + RelativePath="..\cpp\road\RoadError.cpp" + > + </File> + <File + RelativePath="..\cpp\road\RoadLogEvent.cpp" + > + </File> + <File + RelativePath="..\cpp\UsingQhullLib.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + <File + RelativePath="..\cpp\Coordinates.h" + > + </File> + <File + RelativePath="..\cpp\functionObjects.h" + > + </File> + <File + RelativePath="..\src\mem.h" + > + </File> + <File + RelativePath="..\cpp\PointCoordinates.h" + > + </File> + <File + RelativePath="..\html\qhull-cpp.xml" + > + </File> + <File + RelativePath="..\cpp\Qhull.h" + > + </File> + <File + RelativePath="..\cpp\QhullError.h" + > + </File> + <File + RelativePath="..\cpp\QhullEvent.h" + > + </File> + <File + RelativePath="..\cpp\QhullFacet.h" + > + </File> + <File + RelativePath="..\cpp\QhullFacetList.h" + > + </File> + <File + RelativePath="..\cpp\QhullFacetSet.h" + > + </File> + <File + RelativePath="..\cpp\QhullHyperplane.h" + > + </File> + <File + RelativePath="..\cpp\QhullIterator.h" + > + </File> + <File + RelativePath="..\src\qhulllib.h" + > + </File> + <File + RelativePath="..\cpp\QhullLinkedList.h" + > + </File> + <File + RelativePath="..\cpp\QhullLog.h" + > + </File> + <File + RelativePath="..\cpp\QhullPoint.h" + > + </File> + <File + RelativePath="..\cpp\QhullPoints.h" + > + </File> + <File + RelativePath="..\cpp\QhullPointSet.h" + > + </File> + <File + RelativePath="..\cpp\QhullQh.h" + > + </File> + <File + RelativePath="..\cpp\QhullRidge.h" + > + </File> + <File + RelativePath="..\cpp\QhullSet.h" + > + </File> + <File + RelativePath="..\cpp\QhullSets.h" + > + </File> + <File + RelativePath="..\cpp\QhullStat.h" + > + </File> + <File + RelativePath="..\cpp\QhullVertex.h" + > + </File> + <File + RelativePath="..\cpp\QhullVertexSet.h" + > + </File> + <File + RelativePath="..\..\..\..\Qt\4.5.2\src\corelib\tools\qiterator.h" + > + </File> + <File + RelativePath="..\..\..\..\Qt\4.5.2\src\corelib\tools\qlinkedlist.h" + > + </File> + <File + RelativePath="..\..\..\..\Qt\4.5.2\src\corelib\tools\qlist.h" + > + </File> + <File + RelativePath="..\src\qset.h" + > + </File> + <File + RelativePath="..\..\..\..\Qt\4.5.2\src\corelib\tools\qvector.h" + > + </File> + <File + RelativePath="..\cpp\RboxPoints.h" + > + </File> + <File + RelativePath="..\cpp\road\RoadError.h" + > + </File> + <File + RelativePath="..\cpp\road\RoadLogEvent.h" + > + </File> + <File + RelativePath="..\cpp\unused\unused.h" + > + </File> + <File + RelativePath="..\cpp\UsingQhullLib.h" + > + </File> + </Filter> + <File + RelativePath="..\src\Changes.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vcproj/qhulllib.vcproj b/vcproj/qhulllib.vcproj new file mode 100644 index 0000000..2198f4a --- /dev/null +++ b/vcproj/qhulllib.vcproj @@ -0,0 +1,635 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="qhulllib" + ProjectGUID="{D1377F6B-7868-460C-9FC5-489C32A3D08F}" + RootNamespace="qhull" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="..\tmp\qhulllib\Release" + IntermediateDirectory="..\tmp\qhulllib\Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="../" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;NDEBUG" + StringPooling="true" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + PrecompiledHeaderFile="..\tmp\qhulllib\Release/qhulllib.pch" + AssemblerListingLocation="..\tmp\qhulllib\Release/" + ObjectFile="..\tmp\qhulllib\Release/" + ProgramDataBaseFileName="..\tmp\qhulllib\Release/" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="..\tmp\qhulllib\Release\qhull.lib" + SuppressStartupBanner="true" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="..\tmp\qhulllib\Debug" + IntermediateDirectory="..\tmp\qhulllib\Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;_DEBUG" + ExceptionHandling="0" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + DisableLanguageExtensions="true" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\qhulllib\Debug/qhulllib.pch" + AssemblerListingLocation="..\tmp\qhulllib\Debug/" + ObjectFile="..\tmp\qhulllib\Debug/" + ProgramDataBaseFileName="..\tmp\qhulllib\Debug/" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + ShowIncludes="false" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="..\tmp\qhulllib\Debug\qhull.lib" + SuppressStartupBanner="true" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + > + <File + RelativePath="..\src\geom.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\geom2.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\global.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\io.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\mem.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\merge.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\poly.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\poly2.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\qhulllib.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\qset.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\random.c" + > + </File> + <File + RelativePath="..\src\rboxlib.c" + > + </File> + <File + RelativePath="..\src\stat.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\user.c" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\usermem.c" + > + </File> + <File + RelativePath="..\src\userprintf.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + <File + RelativePath="..\src\geom.h" + > + </File> + <File + RelativePath="..\src\io.h" + > + </File> + <File + RelativePath="..\src\mem.h" + > + </File> + <File + RelativePath="..\src\merge.h" + > + </File> + <File + RelativePath="..\src\poly.h" + > + </File> + <File + RelativePath="..\src\qhull_a.h" + > + </File> + <File + RelativePath="..\src\qhulllib.h" + > + </File> + <File + RelativePath="..\src\qset.h" + > + </File> + <File + RelativePath="..\src\random.h" + > + </File> + <File + RelativePath="..\src\stat.h" + > + </File> + <File + RelativePath="..\src\user.h" + > + </File> + </Filter> + <Filter + Name="Other Files" + Filter="txt,groovy,htm" + > + <File + RelativePath="..\src\index.htm" + > + </File> + <File + RelativePath="..\src\Make-config.sh" + > + </File> + <File + RelativePath="..\src\Makefile.txt" + > + </File> + <File + RelativePath="..\src\Mborland" + > + </File> + <File + RelativePath="..\src\qh-geom.htm" + > + </File> + <File + RelativePath="..\src\qh-globa.htm" + > + </File> + <File + RelativePath="..\html\qh-impre.htm" + DeploymentContent="true" + > + </File> + <File + RelativePath="..\html\qh-code.htm" + DeploymentContent="true" + > + </File> + <File + RelativePath="..\src\qh-io.htm" + > + </File> + <File + RelativePath="..\src\qh-mem.htm" + > + </File> + <File + RelativePath="..\src\qh-merge.htm" + > + </File> + <File + RelativePath="..\html\qh-optf.htm" + DeploymentContent="true" + > + </File> + <File + RelativePath="..\html\qh-opto.htm" + DeploymentContent="true" + > + </File> + <File + RelativePath="..\src\qh-poly.htm" + > + </File> + <File + RelativePath="..\src\qh-qhull.htm" + > + </File> + <File + RelativePath="..\src\qh-set.htm" + > + </File> + <File + RelativePath="..\src\qh-stat.htm" + > + </File> + <File + RelativePath="..\src\qh-user.htm" + > + </File> + <File + RelativePath="..\html\qhalf.htm" + DeploymentContent="true" + > + </File> + <File + RelativePath="..\html\qhull.htm" + DeploymentContent="true" + > + </File> + <File + RelativePath="..\news\update-msgcode.groovy" + > + </File> + </Filter> + <File + RelativePath="..\news\qhull-news.html" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vcproj/qhulltest.vcproj b/vcproj/qhulltest.vcproj new file mode 100644 index 0000000..7112d98 --- /dev/null +++ b/vcproj/qhulltest.vcproj @@ -0,0 +1,699 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="qhulltest" + ProjectGUID="{AFDCA33D-3D74-3866-BAE1-97033FE213AA}" + RootNamespace="qhulltest" + Keyword="Qt4VSv1.0" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\qhulltest\Debug" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + WarningLevel="0" + DefaultCharType="0" + EnableErrorChecks="1" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="-Zm200 -EHsc -w34100 -w34189" + Optimization="4" + AdditionalIncludeDirectories=".,..\cpp,..\..\cpp,..\src,..\..\src,..\tmp,..\..\tmp,"$(QTDIR)\include\QtCore","$(QTDIR)\include\QtGui","$(QTDIR)\include","$(QTDIR)\include\QtTest","$(QTDIR)\include\ActiveQt",$(QTDIR)\mkspecs\win32-msvc2005" + PreprocessorDefinitions="UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_DLL,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT" + GeneratePreprocessedFile="0" + RuntimeLibrary="3" + BufferSecurityCheck="false" + TreatWChar_tAsBuiltInType="false" + RuntimeTypeInfo="true" + UsePrecompiledHeader="1" + PrecompiledHeaderThrough="../road/RoadTest.h" + AssemblerListingLocation="..\tmp\qhulltest\Debug\" + ObjectFile="..\tmp\qhulltest\Debug\" + ProgramDataBaseFileName="..\tmp\qhulltest" + WarningLevel="3" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + ShowIncludes="false" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_DLL,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT,_DEBUG" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + IgnoreImportLibrary="true" + AdditionalOptions="/NODEFAULTLIB:LIBCMTD " + AdditionalDependencies="../tmp/qhullcpp/Debug/qhullcpp.lib ../tmp/qhulllib/Debug/qhull.lib $(QTDIR)\lib\QtTestd4.lib $(QTDIR)\lib\QtGuid4.lib $(QTDIR)\lib\QtCored4.lib" + OutputFile="..\qhulltest.exe" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="c:\Qt\4.5.2\lib" + IgnoreAllDefaultLibraries="false" + GenerateDebugInformation="true" + ProgramDatabaseFile="" + 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" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\qhulltest\Release" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + WarningLevel="0" + DefaultCharType="0" + EnableErrorChecks="1" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="-Zm200 -EHsc -w34100 -w34189" + Optimization="2" + AdditionalIncludeDirectories=".,..\cpp,..\..\cpp,..\src,..\..\src,..\tmp,..\..\tmp,"\Qt\4.5.2\include\QtCore","\Qt\4.5.2\include\QtCore","\Qt\4.5.2\include\QtGui","\Qt\4.5.2\include\QtGui","\Qt\4.5.2\include","\Qt\4.5.2\include\QtTest","\Qt\4.5.2\include\ActiveQt",\Qt\4.5.2\mkspecs\win32-msvc2005" + PreprocessorDefinitions="QT_NO_DEBUG,NDEBUG,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_DLL,QT_NO_DEBUG,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT,NDEBUG" + GeneratePreprocessedFile="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + TreatWChar_tAsBuiltInType="false" + RuntimeTypeInfo="true" + AssemblerListingLocation="..\tmp\qhulltest\Release\" + ObjectFile="..\tmp\qhulltest\Release\" + ProgramDataBaseFileName=".\" + WarningLevel="3" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="QT_NO_DEBUG,NDEBUG,UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_DLL,QT_NO_DEBUG,QT_GUI_LIB,QT_CORE_LIB,QT_THREAD_SUPPORT" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + IgnoreImportLibrary="true" + AdditionalDependencies="../tmp/qhullcpp/Debug/qhullcpp.lib c:\Qt\4.5.2\lib\QtTest4.lib c:\Qt\4.5.2\lib\QtGui4.lib c:\Qt\4.5.2\lib\QtCore4.lib" + OutputFile="..\qhulltest.exe" + LinkIncremental="1" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="c:\Qt\4.5.2\lib" + GenerateDebugInformation="false" + ProgramDatabaseFile="" + 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" + /> + </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="..\cpp\qhulltest\Coordinates_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\PointCoordinates_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\Qhull_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullFacet_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullFacetList_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullFacetSet_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullHyperplane_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullLinkedList_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullPoint_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullPoints_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullPointSet_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullRidge_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullSet_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\qhulltest.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\QhullVertex_test.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\RboxPoints_test.cpp" + > + </File> + <File + RelativePath="..\cpp\road\RoadTest.cpp" + > + </File> + <File + RelativePath="..\cpp\qhulltest\UsingQhullLib_test.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\cpp\road\RoadTest.h" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing RoadTest.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\road\RoadTest.h" -o ".\..\tmp\moc\moc_RoadTest.cpp" "-f../road/RoadTest.h" "-f..\..\cpp\road\RoadTest.h"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\road\RoadTest.h" + Outputs="".\..\tmp\moc\moc_RoadTest.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing RoadTest.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DQT_NO_DEBUG -DNDEBUG -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DNDEBUG -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"\Qt\4.5.2\include\QtCore\." -I"\Qt\4.5.2\include\QtCore\." -I"\Qt\4.5.2\include\QtGui\." -I"\Qt\4.5.2\include\QtGui\." -I"\Qt\4.5.2\include\." -I"\Qt\4.5.2\include\QtTest\." -I"\Qt\4.5.2\include\ActiveQt\." -I"\Qt\4.5.2\mkspecs\win32-msvc2005\." "..\cpp\road\RoadTest.h" -o ".\..\tmp\moc\moc_RoadTest.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\road\RoadTest.h" + Outputs="".\..\tmp\moc\moc_RoadTest.cpp"" + /> + </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="..\tmp\moc\Coordinates_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing Coordinates_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\Coordinates_test.cpp" -o ".\..\tmp\moc\Coordinates_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\Coordinates_test.cpp" + Outputs="".\..\tmp\moc\Coordinates_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\PointCoordinates_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing PointCoordinates_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\PointCoordinates_test.cpp" -o ".\..\tmp\moc\PointCoordinates_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\PointCoordinates_test.cpp" + Outputs="".\..\tmp\moc\PointCoordinates_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing PointCoordinates_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DQT_NO_DEBUG -DNDEBUG -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DNDEBUG -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"\Qt\4.5.2\include\QtCore\." -I"\Qt\4.5.2\include\QtCore\." -I"\Qt\4.5.2\include\QtGui\." -I"\Qt\4.5.2\include\QtGui\." -I"\Qt\4.5.2\include\." -I"\Qt\4.5.2\include\QtTest\." -I"\Qt\4.5.2\include\ActiveQt\." -I"\Qt\4.5.2\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\PointCoordinates_test.cpp" -o ".\..\tmp\moc\PointCoordinates_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\PointCoordinates_test.cpp" + Outputs="".\..\tmp\moc\PointCoordinates_test.moc"" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\Qhull_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing Qhull_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\Qhull_test.cpp" -o ".\..\tmp\moc\Qhull_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\Qhull_test.cpp" + Outputs="".\..\tmp\moc\Qhull_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullFacet_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullFacet_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullFacet_test.cpp" -o ".\..\tmp\moc\QhullFacet_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullFacet_test.cpp" + Outputs="".\..\tmp\moc\QhullFacet_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullFacetList_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullFacetList_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullFacetList_test.cpp" -o ".\..\tmp\moc\QhullFacetList_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullFacetList_test.cpp" + Outputs="".\..\tmp\moc\QhullFacetList_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullFacetSet_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullFacetSet_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullFacetSet_test.cpp" -o ".\..\tmp\moc\QhullFacetSet_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullFacetSet_test.cpp" + Outputs="".\..\tmp\moc\QhullFacetSet_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullHyperplane_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullHyperplane_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullHyperplane_test.cpp" -o ".\..\tmp\moc\QhullHyperplane_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullHyperplane_test.cpp" + Outputs="".\..\tmp\moc\QhullHyperplane_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullHyperplane_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DQT_NO_DEBUG -DNDEBUG -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DNDEBUG -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"\Qt\4.5.2\include\QtCore\." -I"\Qt\4.5.2\include\QtCore\." -I"\Qt\4.5.2\include\QtGui\." -I"\Qt\4.5.2\include\QtGui\." -I"\Qt\4.5.2\include\." -I"\Qt\4.5.2\include\QtTest\." -I"\Qt\4.5.2\include\ActiveQt\." -I"\Qt\4.5.2\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullHyperplane_test.cpp" -o ".\..\tmp\moc\QhullHyperplane_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullHyperplane_test.cpp" + Outputs="".\..\tmp\moc\QhullHyperplane_test.moc"" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullLinkedList_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullLinkedList_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullLinkedList_test.cpp" -o ".\..\tmp\moc\QhullLinkedList_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullLinkedList_test.cpp" + Outputs="".\..\tmp\moc\QhullLinkedList_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullPoint_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullPoint_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullPoint_test.cpp" -o ".\..\tmp\moc\QhullPoint_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullPoint_test.cpp" + Outputs="".\..\tmp\moc\QhullPoint_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullPoints_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullPoints_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullPoints_test.cpp" -o ".\..\tmp\moc\QhullPoints_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullPoints_test.cpp" + Outputs="".\..\tmp\moc\QhullPoints_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullPointSet_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullPointSet_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullPointSet_test.cpp" -o ".\..\tmp\moc\QhullPointSet_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullPointSet_test.cpp" + Outputs="".\..\tmp\moc\QhullPointSet_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullRidge_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullRidge_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullRidge_test.cpp" -o ".\..\tmp\moc\QhullRidge_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullRidge_test.cpp" + Outputs="".\..\tmp\moc\QhullRidge_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullSet_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullSet_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullSet_test.cpp" -o ".\..\tmp\moc\QhullSet_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullSet_test.cpp" + Outputs="".\..\tmp\moc\QhullSet_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\QhullVertex_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing QhullVertex_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\QhullVertex_test.cpp" -o ".\..\tmp\moc\QhullVertex_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\QhullVertex_test.cpp" + Outputs="".\..\tmp\moc\QhullVertex_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\RboxPoints_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing RboxPoints_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\RboxPoints_test.cpp" -o ".\..\tmp\moc\RboxPoints_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\RboxPoints_test.cpp" + Outputs="".\..\tmp\moc\RboxPoints_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\tmp\moc\UsingQhullLib_test.moc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing UsingQhullLib_test.cpp..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I".\." -I".\..\cpp\." -I".\..\..\cpp\." -I".\..\src\." -I".\..\..\src\." -I".\..\tmp\." -I".\..\..\tmp\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\." -I"$(QTDIR)\include\QtTest\." -I"$(QTDIR)\include\ActiveQt\." -I"$(QTDIR)\mkspecs\win32-msvc2005\." "..\cpp\qhulltest\UsingQhullLib_test.cpp" -o ".\..\tmp\moc\UsingQhullLib_test.moc"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";..\cpp\qhulltest\UsingQhullLib_test.cpp" + Outputs="".\..\tmp\moc\UsingQhullLib_test.moc"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + </Filter> + </Files> + <Globals> + <Global + Name="QtVersion" + Value="4.5.2" + /> + <Global + Name="QtVersion Win32" + Value="4.5.3" + /> + </Globals> +</VisualStudioProject> diff --git a/vcproj/rbox.vcproj b/vcproj/rbox.vcproj new file mode 100644 index 0000000..f6c69dc --- /dev/null +++ b/vcproj/rbox.vcproj @@ -0,0 +1,236 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="rbox" + ProjectGUID="{D137FB9B-7868-460C-9FC5-489C32A3D08F}" + RootNamespace="rbox" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\rbox\Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="../" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;NDEBUG" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\rbox\Release/rbox.pch" + AssemblerListingLocation="..\tmp\rbox\Release/" + ObjectFile="..\tmp\rbox\Release/" + ProgramDataBaseFileName="..\tmp\rbox\Release/" + BrowseInformation="1" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions=""..\tmp\qhulllib\Release\qhull.lib"" + OutputFile="..\rbox.exe" + LinkIncremental="0" + /> + <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="Debug|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\rbox\Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;_DEBUG" + ExceptionHandling="0" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\rbox\Debug/rbox.pch" + AssemblerListingLocation="..\tmp\rbox\Debug/" + ObjectFile="..\tmp\rbox\Debug/" + ProgramDataBaseFileName="..\tmp\rbox\Debug/" + BrowseInformation="1" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions=""..\tmp\qhulllib\Debug\qhull.lib"" + OutputFile="..\rbox.exe" + LinkIncremental="0" + GenerateDebugInformation="true" + /> + <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" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + > + <File + RelativePath="..\src\rbox.c" + > + </File> + <File + RelativePath="..\src\rboxlib.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + <File + RelativePath="..\src\qhulllib.h" + > + </File> + <File + RelativePath="..\src\user.h" + > + </File> + </Filter> + <Filter + Name="Other Files" + Filter="txt,groovy,htm" + > + <File + RelativePath="..\html\rbox.txt" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vcproj/user_eg3.vcproj b/vcproj/user_eg3.vcproj new file mode 100644 index 0000000..d3b233d --- /dev/null +++ b/vcproj/user_eg3.vcproj @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="user_eg3" + ProjectGUID="{B94D6587-1030-4EA0-8322-E9B2902A9AC4}" + RootNamespace="user_eg3" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\user_eg3\Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="../" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;NDEBUG" + StringPooling="true" + ExceptionHandling="1" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\user_eg3\Release/user_eg3.pch" + AssemblerListingLocation="..\tmp\user_eg3\Release/" + ObjectFile="..\tmp\user_eg3\Release/" + ProgramDataBaseFileName="..\tmp\user_eg3\Release/" + BrowseInformation="1" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions=""..\tmp\qhulllib\Release\qhull.lib" "..\tmp\qhullcpp\Release\qhullcpp.lib" " + OutputFile="..\user_eg3.exe" + LinkIncremental="0" + /> + <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="Debug|Win32" + OutputDirectory="." + IntermediateDirectory="..\tmp\user_eg3\Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="C:\Qt\4.5.2\include" + PreprocessorDefinitions="_LIB;UNICODE=1;WIN32;_DEBUG" + ExceptionHandling="1" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="false" + PrecompiledHeaderFile="..\tmp\user_eg3\Debug/user_eg3.pch" + AssemblerListingLocation="..\tmp\user_eg3\Debug/" + ObjectFile="..\tmp\user_eg3\Debug/" + ProgramDataBaseFileName="..\tmp\user_eg3\Debug/" + BrowseInformation="1" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions=""..\tmp\qhulllib\Debug\qhull.lib" "..\tmp\qhullcpp\Debug\qhullcpp.lib" " + OutputFile="../user_eg3.exe" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + /> + <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" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\cpp\user_eg3.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> -- GitLab