1 /****************************************************************************
2 **
3 ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
4 ** $Id: //main/2019/qhull/src/libqhullcpp/QhullRidge.cpp#2 $$Change: 2953 $
5 ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
6 **
7 ****************************************************************************/
8 
9 #//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
10 
11 #include "libqhullcpp/QhullRidge.h"
12 
13 #include "libqhullcpp/QhullSets.h"
14 #include "libqhullcpp/QhullVertex.h"
15 #include "libqhullcpp/Qhull.h"
16 
17 #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
18 #pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
19 #pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
20 #endif
21 
22 namespace orgQhull {
23 
24 #//!\name Class objects
25 ridgeT QhullRidge::
26 s_empty_ridge= {NULL,NULL,NULL,0,    // must match ridgeT -Wmissing-field-initializers
27                 false,false,false,false,false,false,false};
28 
29 #//!\name Constructors
30 
QhullRidge(const Qhull & q)31 QhullRidge::QhullRidge(const Qhull &q)
32 : qh_ridge(&s_empty_ridge)
33 , qh_qh(q.qh())
34 {
35 }//Default
36 
QhullRidge(const Qhull & q,ridgeT * r)37 QhullRidge::QhullRidge(const Qhull &q, ridgeT *r)
38 : qh_ridge(r ? r : &s_empty_ridge)
39 , qh_qh(q.qh())
40 {
41 }//ridgeT
42 
43 #//!\name foreach
44 
45 //! Return True if nextRidge3d
46 //! Simplicial facets may have incomplete ridgeSets
47 //! Does not use qh_errexit()
48 bool QhullRidge::
hasNextRidge3d(const QhullFacet & f) const49 hasNextRidge3d(const QhullFacet &f) const
50 {
51     if(!qh_qh){
52         return false;
53     }
54     vertexT *v= 0;
55     // Does not call qh_errexit(), TRY_QHULL_ not needed
56     ridgeT *ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
57     return (ridge!=0);
58 }//hasNextRidge3d
59 
60 //! Return next ridge and optional vertex for a 3d facet and ridge
61 //! Does not use qh_errexit()
62 QhullRidge QhullRidge::
nextRidge3d(const QhullFacet & f,QhullVertex * nextVertex) const63 nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const
64 {
65     vertexT *v= 0;
66     ridgeT *ridge= 0;
67     if(qh_qh){
68         // Does not call qh_errexit(), TRY_QHULL_ not needed
69         ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
70         if(!ridge){
71             throw QhullError(10030, "Qhull error nextRidge3d:  missing next ridge for facet %d ridge %d.  Does facet contain ridge?", f.id(), id());
72         }
73     }
74     if(nextVertex!=0){
75         *nextVertex= QhullVertex(qh_qh, v);
76     }
77     return QhullRidge(qh_qh, ridge);
78 }//nextRidge3d
79 
80 }//namespace orgQhull
81 
82 #//!\name Global functions
83 
84 using std::endl;
85 using std::ostream;
86 using orgQhull::QhullRidge;
87 using orgQhull::QhullVertex;
88 
89 ostream &
operator <<(ostream & os,const QhullRidge & r)90 operator<<(ostream &os, const QhullRidge &r)
91 {
92     os << r.print("");
93     return os;
94 }//<< QhullRidge
95 
96 //! Duplicate of qh_printridge [io_r.c]
97 ostream &
operator <<(ostream & os,const QhullRidge::PrintRidge & pr)98 operator<<(ostream &os, const QhullRidge::PrintRidge &pr)
99 {
100     if(*pr.print_message){
101         os << pr.print_message << " ";
102     }else{
103         os << "     - ";
104     }
105     QhullRidge r= *pr.ridge;
106     os << "r" << r.id();
107     if(r.getRidgeT()->tested){
108         os << " tested";
109     }
110     if(r.getRidgeT()->nonconvex){
111         os << " nonconvex";
112     }
113     if(r.getRidgeT()->mergevertex){
114       os << " mergevertex";
115     }
116     if(r.getRidgeT()->mergevertex2){
117       os << " mergevertex2";
118     }
119     if(r.getRidgeT()->simplicialtop){
120       os << " simplicialtop";
121     }
122     if(r.getRidgeT()->simplicialbot){
123       os << " simplicialbot";
124     }
125     os << endl;
126     os << r.vertices().print("           vertices:");
127     if(r.getRidgeT()->top && r.getRidgeT()->bottom){
128         os << "           between f" << r.topFacet().id() << " and f" << r.bottomFacet().id() << endl;
129     }else if(r.getRidgeT()->top){
130         os << "           top f" << r.topFacet().id() << endl;
131     }else if(r.getRidgeT()->bottom){
132         os << "           bottom f" << r.bottomFacet().id() << endl;
133     }
134 
135     return os;
136 }//<< PrintRidge
137