1 /**************************************************************************** 2 ** 3 ** Copyright (c) 2008-2015 C.B. Barber. All rights reserved. 4 ** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.h#2 $$Change: 2079 $ 5 ** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $ 6 ** 7 ****************************************************************************/ 8 9 #ifndef QHULLQH_H 10 #define QHULLQH_H 11 12 #include "libqhull_r/qhull_ra.h" 13 14 #include <string> 15 16 #ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4 17 #pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */ 18 /* setjmp should not be implemented with 'catch' */ 19 #endif 20 21 //! Use QH_TRY_ or QH_TRY_NOTHROW_ to call a libqhull_r routine that may invoke qh_errexit() 22 //! QH_TRY_(qh){...} qh->NOerrexit=true; 23 //! No object creation -- longjmp() skips object destructors 24 //! To test for error when done -- qh->maybeThrowQhullMessage(QH_TRY_status); 25 //! Use the same compiler for QH_TRY_, libqhullcpp, and libqhull_r. setjmp() is not portable between compilers. 26 27 #define QH_TRY_ERROR 10071 28 29 #define QH_TRY_(qh) \ 30 int QH_TRY_status; \ 31 if(qh->NOerrexit){ \ 32 qh->NOerrexit= False; \ 33 QH_TRY_status= setjmp(qh->errexit); \ 34 }else{ \ 35 throw QhullError(QH_TRY_ERROR, "Cannot invoke QH_TRY_() from inside a QH_TRY_. Or missing 'qh->NOerrexit=true' after previously called QH_TRY_(qh){...}"); \ 36 } \ 37 if(!QH_TRY_status) 38 39 #define QH_TRY_NO_THROW_(qh) \ 40 int QH_TRY_status; \ 41 if(qh->NOerrexit){ \ 42 qh->NOerrexit= False; \ 43 QH_TRY_status= setjmp(qh->errexit); \ 44 }else{ \ 45 QH_TRY_status= QH_TRY_ERROR; \ 46 } \ 47 if(!QH_TRY_status) 48 49 namespace orgQhull { 50 51 #//!\name Defined here 52 //! QhullQh -- Qhull's global data structure, qhT, as a C++ class 53 class QhullQh; 54 55 //! POD type equivalent to qhT. No virtual members 56 class QhullQh : public qhT { 57 58 #//!\name Constants 59 60 #//!\name Fields 61 private: 62 int qhull_status; //!< qh_ERRnone if valid 63 std::string qhull_message; //!< Returned messages from libqhull_r 64 std::ostream * error_stream; //!< overrides errorMessage, use appendQhullMessage() 65 std::ostream * output_stream; //!< send output to stream 66 double factor_epsilon; //!< Factor to increase ANGLEround and DISTround for hyperplane equality 67 bool use_output_stream; //!< True if using output_stream 68 69 friend void ::qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ); 70 71 static const double default_factor_epsilon; //!< Default factor_epsilon is 1.0, never updated 72 73 #//!\name Constructors 74 public: 75 QhullQh(); 76 ~QhullQh(); 77 private: 78 //!disable copy constructor and assignment 79 QhullQh(const QhullQh &); 80 QhullQh & operator=(const QhullQh &); 81 public: 82 83 #//!\name GetSet factorEpsilon()84 double factorEpsilon() const { return factor_epsilon; } setFactorEpsilon(double a)85 void setFactorEpsilon(double a) { factor_epsilon= a; } disableOutputStream()86 void disableOutputStream() { use_output_stream= false; } enableOutputStream()87 void enableOutputStream() { use_output_stream= true; } 88 89 #//!\name Messaging 90 void appendQhullMessage(const std::string &s); 91 void clearQhullMessage(); 92 std::string qhullMessage() const; hasOutputStream()93 bool hasOutputStream() const { return use_output_stream; } 94 bool hasQhullMessage() const; 95 void maybeThrowQhullMessage(int exitCode); 96 void maybeThrowQhullMessage(int exitCode, int noThrow) throw(); 97 int qhullStatus() const; 98 void setErrorStream(std::ostream *os); 99 void setOutputStream(std::ostream *os); 100 101 #//!\name Methods angleEpsilon()102 double angleEpsilon() const { return this->ANGLEround*factor_epsilon; } //!< Epsilon for hyperplane angle equality 103 void checkAndFreeQhullMemory(); distanceEpsilon()104 double distanceEpsilon() const { return this->DISTround*factor_epsilon; } //!< Epsilon for distance to hyperplane 105 106 };//class QhullQh 107 108 }//namespace orgQhull 109 110 #endif // QHULLQH_H 111