1 /****************************************************************************
2 **
3 ** Copyright (c) 2008-2012 C.B. Barber. All rights reserved.
4 ** $Id: //main/2011/qhull/src/libqhullcpp/QhullQh.cpp#3 $$Change: 1464 $
5 ** $DateTime: 2012/01/25 22:58:41 $$Author: bbarber $
6 **
7 ****************************************************************************/
8 
9 #//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
10 
11 
12 
13 #include "QhullError.h"
14 #include "QhullQh.h"
15 #include "QhullStat.h"
16 
17 #include <sstream>
18 #include <iostream>
19 
20 using std::cerr;
21 using std::string;
22 using std::vector;
23 using std::ostream;
24 
25 #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
26 #pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
27 #pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
28 #endif
29 
30 namespace orgQhull {
31 
32 #//Global variables
33 
34 #//Constructor, destructor, etc.
35 
36 //! If qh_QHpointer==0, invoke with placement new on qh_qh;
37 //! Sets qh_qh and qh_qhstat.  Need to reset before UsingLibQhull.
38 //! Derived from qh_new_qhull[user.c]
39 QhullQh::
QhullQh()40 QhullQh()
41 {
42     static boolT firstcall = True;
43 
44     if(firstcall){
45         if(qhmem.BUFinit!=0){
46             throw QhullError(10017, "Qhull error: qhmem already initialized by another class.");
47         }
48         qh_meminit(NULL);
49         firstcall= False;
50     }
51     // QhullQh() and UsingLibQhull() are the same
52 #if qh_QHpointer
53     if(qh_qh){
54         if(qh old_qhstat){
55             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);
56         }
57         qh old_qhstat= qh_qhstat;
58         qh old_tempstack= qhmem.tempstack;
59         qh_qhstat= 0;
60         qhmem.tempstack= 0;
61     }
62     qh_qh= static_cast<qhT*>(this);
63 #else
64     if(strncmp(qh qhull, "qhull", 5) == 0){
65         throw QhullError(10022, "Qhull error: Qhull already initialized as run %d", qh run_id);
66     }
67 #endif
68     // NOerrors -- Does not call qh_errexit()
69     qh_initstatistics();
70     // NOerrors -- Does not call qh_errexit()
71     qh_initqhull_start2(NULL, NULL, qh_FILEstderr);
72 }//QhullQh
73 
74 //! UsingLibQhull must be declared along with QhullQh
75 QhullQh::
~QhullQh()76 ~QhullQh()
77 {
78 #if qh_QHpointer
79     if(!qh_qh){
80         QhullError e(10042, "Qhull internal error: qh_qh undefined.  Was ~QhullQh() invoked independent of UsingLibQhull?", qh run_id, 0, 0, qh_qh);
81         e.logError();
82     }else if(!qh_qhstat){
83         QhullError e(10043, "Qhull internal error: qh_qhstat null.  Is another thread running?");
84         e.logError();
85     }else if(qh_qh!=this){
86         QhullError e(10044, "Qhull error: ~QhullQh() invoked independent of UsingLibQhull. qh_qh %x (runId %d) vs. QhullQh.runId %d.", qh run_id, run_id, 0.0, qh_qh);
87         e.logError();
88     }else{
89         qh_freeqhull2(qh_ALL); // sets qh.NOerrexit.  Clears struct *qh_qh including run_id, but not qh_qh itself
90     }
91 #else
92     if(&qh_qh!=this){
93         QhullError e(10045, "Qhull error: ~QhullQh() invoked independent of UsingLibQhull. qh_qh %x (runId %d) vs. QhullQh.runId %d.", qh run_id, run_id, 0.0, qh_qh);
94         e.logError();
95     }else{
96         qh_freeqhull2(qh_ALL); // sets qh.NOerrexit.  Clears struct *qh_qh including run_id, but not qh_qh itself
97     }
98 #endif
99 }//~QhullQh
100 
101 #//Parallel Access
102 
103 }//namespace orgQhull
104 
105