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