QhullFacet.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (c) 2008-2011 C.B. Barber. All rights reserved.
00004 ** $Id: //main/2011/qhull/src/libqhullcpp/QhullFacet.cpp#6 $$Change: 1372 $
00005 ** $DateTime: 2011/04/17 19:32:21 $$Author: bbarber $
00006 **
00007 ****************************************************************************/
00008 
00009 #//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
00010 
00011 #include "QhullError.h"
00012 #include "QhullSet.h"
00013 #include "QhullPoint.h"
00014 #include "QhullPointSet.h"
00015 #include "QhullRidge.h"
00016 #include "QhullFacet.h"
00017 #include "QhullFacetSet.h"
00018 #include "QhullVertex.h"
00019 
00020 #include <ostream>
00021 
00022 using std::endl;
00023 using std::string;
00024 using std::vector;
00025 using std::ostream;
00026 
00027 #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
00028 #pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
00029 #pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
00030 #endif
00031 
00032 namespace orgQhull {
00033 
00034 #//class statics
00035 facetT QhullFacet::
00036         s_empty_facet= {0,0,0,0,{0},
00037                 0,0,0,0,0,
00038                 0,0,0,0,0,
00039                 0,0,0,0,0,
00040                 0,0,0,0,0,
00041                 0,0,0,0,0,
00042                 0,0,0,0,0,
00043                 0,0,0,0};
00044 
00045 #//GetSet
00046 
00047 int QhullFacet::
00048 dimension() const
00049 {
00050     if(qh_facet->ridges){
00051         setT *s= qh_facet->ridges;
00052         ridgeT *r= reinterpret_cast<ridgeT *>(SETfirst_(s));
00053         return r ? QhullSetBase::count(r->vertices)+1 : 0;
00054     }else{
00055         return QhullSetBase::count(qh_facet->vertices);
00056     }
00057 }//dimension
00058 
00064 QhullPoint QhullFacet::
00065 getCenter(int qhRunId, qh_PRINT printFormat)
00066 {
00067     UsingLibQhull q(qhRunId);
00068 
00069     if(qh CENTERtype==qh_ASvoronoi){
00070         if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh ATinfinity){
00071             if(!qh_facet->center){
00072                 int exitCode = setjmp(qh errexit);
00073                 if(!exitCode){ // no object creation -- destructors skipped on longjmp()
00074                     qh_facet->center= qh_facetcenter(qh_facet->vertices);
00075                 }
00076                 q.maybeThrowQhullMessage(exitCode);
00077             }
00078             return QhullPoint(qh hull_dim-1, qh_facet->center);
00079         }
00080     }else if(qh CENTERtype==qh_AScentrum){
00081         volatile int numCoords= qh hull_dim;
00082         if(printFormat==qh_PRINTtriangles && qh DELAUNAY){
00083             numCoords--;
00084         }
00085         if(!qh_facet->center){
00086             int exitCode = setjmp(qh errexit);
00087             if(!exitCode){ // no object creation -- destructors skipped on longjmp()
00088                 qh_facet->center= qh_getcentrum(getFacetT());
00089             }
00090             q.maybeThrowQhullMessage(exitCode);
00091         }
00092         return QhullPoint(numCoords, qh_facet->center);
00093     }
00094     return QhullPoint();
00095  }//getCenter
00096 
00099 QhullHyperplane QhullFacet::
00100 innerplane(int qhRunId) const{
00101     UsingLibQhull q(qhRunId);
00102     realT inner;
00103     // Does not error
00104     qh_outerinner(const_cast<facetT *>(getFacetT()), NULL, &inner);
00105     QhullHyperplane h= hyperplane();
00106     h.setOffset(h.offset()-inner); //inner is negative
00107     return h;
00108 }//innerplane
00109 
00112 QhullHyperplane QhullFacet::
00113 outerplane(int qhRunId) const{
00114     UsingLibQhull q(qhRunId);
00115     realT outer;
00116     // Does not error
00117     qh_outerinner(const_cast<facetT *>(getFacetT()), &outer, NULL);
00118     QhullHyperplane h= hyperplane();
00119     h.setOffset(h.offset()-outer); //outer is positive
00120     return h;
00121 }//outerplane
00122 
00125 QhullFacet QhullFacet::
00126 tricoplanarOwner() const
00127 {
00128     if(qh_facet->tricoplanar){
00129         if(qh_facet->isarea){
00130             throw QhullError(10018, "Qhull error: facetArea() or qh_getarea() previously called.  triCoplanarOwner() is not available.");
00131         }
00132         return qh_facet->f.triowner;
00133     }
00134     return 0; // FIXUP QH11009 Should false be the NULL facet or empty facet
00135 }//tricoplanarOwner
00136 
00137 QhullPoint QhullFacet::
00138 voronoiVertex(int qhRunId)
00139 {
00140     if(
00141 #if qh_QHpointer
00142       !qh_qh ||
00143 #endif
00144       qh CENTERtype!=qh_ASvoronoi){
00145           throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
00146     }
00147     return getCenter(qhRunId);
00148 }//voronoiVertex
00149 
00150 #//Value
00151 
00153 double QhullFacet::
00154 facetArea(int qhRunId)
00155 {
00156     if(!qh_facet->isarea){
00157         UsingLibQhull q(qhRunId);
00158         int exitCode = setjmp(qh errexit);
00159         if(!exitCode){ // no object creation -- destructors skipped on longjmp()
00160             qh_facet->f.area= qh_facetarea(qh_facet);
00161             qh_facet->isarea= True;
00162         }
00163         q.maybeThrowQhullMessage(exitCode);
00164     }
00165     return qh_facet->f.area;
00166 }//facetArea
00167 
00168 #//Foreach
00169 
00170 QhullPointSet QhullFacet::
00171 coplanarPoints() const
00172 {
00173     return QhullPointSet(dimension(), qh_facet->coplanarset);
00174 }//coplanarPoints
00175 
00176 QhullFacetSet QhullFacet::
00177 neighborFacets() const
00178 {
00179     return QhullFacetSet(qh_facet->neighbors);
00180 }//neighborFacets
00181 
00182 QhullPointSet QhullFacet::
00183 outsidePoints() const
00184 {
00185     return QhullPointSet(dimension(), qh_facet->outsideset);
00186 }//outsidePoints
00187 
00188 QhullRidgeSet QhullFacet::
00189 ridges() const
00190 {
00191     return QhullRidgeSet(qh_facet->ridges);
00192 }//ridges
00193 
00194 QhullVertexSet QhullFacet::
00195 vertices() const
00196 {
00197     return QhullVertexSet(qh_facet->vertices);
00198 }//vertices
00199 
00200 
00201 }//namespace orgQhull
00202 
00203 #//operator<<
00204 
00205 using std::ostream;
00206 
00207 using orgQhull::QhullFacet;
00208 using orgQhull::QhullFacetSet;
00209 using orgQhull::QhullPoint;
00210 using orgQhull::QhullPointSet;
00211 using orgQhull::QhullRidge;
00212 using orgQhull::QhullRidgeSet;
00213 using orgQhull::QhullSetBase;
00214 using orgQhull::QhullVertexSet;
00215 using orgQhull::UsingLibQhull;
00216 
00217 ostream &
00218 operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
00219 {
00220     QhullFacet f= *pr.facet;
00221     if(f.getFacetT()==0){ // Special values from set iterator
00222         os << " NULLfacet" << endl;
00223         return os;
00224     }
00225     if(f.getFacetT()==qh_MERGEridge){
00226         os << " MERGEridge" << endl;
00227         return os;
00228     }
00229     if(f.getFacetT()==qh_DUPLICATEridge){
00230         os << " DUPLICATEridge" << endl;
00231         return os;
00232     }
00233     os << f.printHeader(pr.run_id);
00234     if(!f.ridges().isEmpty()){
00235         os << f.printRidges(pr.run_id);
00236     }
00237     return os;
00238 }//operator<< PrintFacet
00239 
00243 ostream &
00244 operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
00245 {
00246     facetT *f= pr.facet->getFacetT();
00247     if(qh CENTERtype!=qh_ASvoronoi && qh CENTERtype!=qh_AScentrum){
00248         return os;
00249     }
00250     if (pr.message){
00251         os << pr.message;
00252     }
00253     int numCoords;
00254     if(qh CENTERtype==qh_ASvoronoi){
00255         numCoords= qh hull_dim-1;
00256         if(!f->normal || !f->upperdelaunay || !qh ATinfinity){
00257             if(!f->center){
00258                 f->center= qh_facetcenter(f->vertices);
00259             }
00260             for(int k=0; k<numCoords; k++){
00261                 os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
00262             }
00263         }else{
00264             for(int k=0; k<numCoords; k++){
00265                 os << qh_INFINITE << " "; // FIXUP QH11010 qh_REAL_1
00266             }
00267         }
00268     }else{ // qh CENTERtype==qh_AScentrum
00269         numCoords= qh hull_dim;
00270         if(pr.print_format==qh_PRINTtriangles && qh DELAUNAY){
00271             numCoords--;
00272         }
00273         if(!f->center){
00274             f->center= qh_getcentrum(f);
00275         }
00276         for(int k=0; k<numCoords; k++){
00277             os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
00278         }
00279     }
00280     if(pr.print_format==qh_PRINTgeom && numCoords==2){
00281         os << " 0";
00282     }
00283     os << endl;
00284     return os;
00285 }//operator<< PrintCenter
00286 
00288 ostream &
00289 operator<<(ostream &os, const QhullFacet::PrintFlags &p)
00290 {
00291     const facetT *f= p.facet->getFacetT();
00292     if(p.message){
00293         os << p.message;
00294     }
00295 
00296     os << (p.facet->isTopOrient() ? " top" : " bottom");
00297     if(p.facet->isSimplicial()){
00298         os << " simplicial";
00299     }
00300     if(p.facet->isTriCoplanar()){
00301         os << " tricoplanar";
00302     }
00303     if(p.facet->isUpperDelaunay()){
00304         os << " upperDelaunay";
00305     }
00306     if(f->visible){
00307         os << " visible";
00308     }
00309     if(f->newfacet){
00310         os << " new";
00311     }
00312     if(f->tested){
00313         os << " tested";
00314     }
00315     if(!f->good){
00316         os << " notG";
00317     }
00318     if(f->seen){
00319         os << " seen";
00320     }
00321     if(f->coplanar){
00322         os << " coplanar";
00323     }
00324     if(f->mergehorizon){
00325         os << " mergehorizon";
00326     }
00327     if(f->keepcentrum){
00328         os << " keepcentrum";
00329     }
00330     if(f->dupridge){
00331         os << " dupridge";
00332     }
00333     if(f->mergeridge && !f->mergeridge2){
00334         os << " mergeridge1";
00335     }
00336     if(f->mergeridge2){
00337         os << " mergeridge2";
00338     }
00339     if(f->newmerge){
00340         os << " newmerge";
00341     }
00342     if(f->flipped){
00343         os << " flipped";
00344     }
00345     if(f->notfurthest){
00346         os << " notfurthest";
00347     }
00348     if(f->degenerate){
00349         os << " degenerate";
00350     }
00351     if(f->redundant){
00352         os << " redundant";
00353     }
00354     os << endl;
00355     return os;
00356 }//operator<< PrintFlags
00357 
00359 ostream &
00360 operator<<(ostream &os, const QhullFacet::PrintHeader &pr)
00361 {
00362     QhullFacet facet= *pr.facet;
00363     facetT *f= facet.getFacetT();
00364     os << "- f" << facet.id() << endl;
00365     os << facet.printFlags("    - flags:");
00366     if(f->isarea){
00367         os << "    - area: " << f->f.area << endl; //FIXUP QH11010 2.2g
00368     }else if(qh NEWfacets && f->visible && f->f.replace){
00369         os << "    - replacement: f" << f->f.replace->id << endl;
00370     }else if(f->newfacet){
00371         if(f->f.samecycle && f->f.samecycle != f){
00372             os << "    - shares same visible/horizon as f" << f->f.samecycle->id << endl;
00373         }
00374     }else if(f->tricoplanar /* !isarea */){
00375         if(f->f.triowner){
00376             os << "    - owner of normal & centrum is facet f" << f->f.triowner->id << endl;
00377         }
00378     }else if(f->f.newcycle){
00379         os << "    - was horizon to f" << f->f.newcycle->id << endl;
00380     }
00381     if(f->nummerge){
00382         os << "    - merges: " << f->nummerge << endl;
00383     }
00384     os << facet.hyperplane().print("    - normal: ", "\n    - offset: "); // FIXUP QH11010 %10.7g
00385     if(qh CENTERtype==qh_ASvoronoi || f->center){
00386         os << facet.printCenter(pr.run_id, qh_PRINTfacets, "    - center: ");
00387     }
00388 #if qh_MAXoutside
00389     if(f->maxoutside > qh DISTround){
00390         os << "    - maxoutside: " << f->maxoutside << endl; //FIXUP QH11010 %10.7g
00391     }
00392 #endif
00393     QhullPointSet ps= facet.outsidePoints();
00394     if(!ps.isEmpty()){
00395         QhullPoint furthest= ps.last();
00396         if (ps.size() < 6) {
00397             os << "    - outside set(furthest p" << furthest.id(pr.run_id) << "):" << endl;
00398             for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
00399                 QhullPoint p= *i;
00400                 os << p.print(pr.run_id, "     ");
00401             }
00402         }else if(ps.size()<21){
00403             os << ps.print(pr.run_id, "    - outside set:");
00404         }else{
00405             os << "    - outside set:  " << ps.size() << " points.";
00406             os << furthest.print(pr.run_id, "  Furthest");
00407         }
00408 #if !qh_COMPUTEfurthest
00409         os << "    - furthest distance= " << f->furthestdist << endl; //FIXUP QH11010 %2.2g
00410 #endif
00411     }
00412     QhullPointSet cs= facet.coplanarPoints();
00413     if(!cs.isEmpty()){
00414         QhullPoint furthest= cs.last();
00415         if (cs.size() < 6) {
00416             os << "    - coplanar set(furthest p" << furthest.id(pr.run_id) << "):" << endl;
00417             for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
00418                 QhullPoint p= *i;
00419                 os << p.print(pr.run_id, "     ");
00420             }
00421         }else if(cs.size()<21){
00422             os << cs.print(pr.run_id, "    - coplanar set:");
00423         }else{
00424             os << "    - coplanar set:  " << cs.size() << " points.";
00425             os << furthest.print(pr.run_id, "  Furthest");
00426         }
00427         zinc_(Zdistio);
00428         double d= facet.distance(furthest);
00429         os << "      furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
00430     }
00431     QhullVertexSet vs= facet.vertices();
00432     if(!vs.isEmpty()){
00433         os << vs.print(pr.run_id, "    - vertices:");
00434     }
00435     QhullFacetSet fs= facet.neighborFacets();
00436     fs.selectAll();
00437     if(!fs.isEmpty()){
00438         os << fs.printIdentifiers("    - neighboring facets:");
00439     }
00440     return os;
00441 }//operator<< PrintHeader
00442 
00443 
00446 ostream &
00447 operator<<(ostream &os, const QhullFacet::PrintRidges &pr)
00448 {
00449     const QhullFacet facet= *pr.facet;
00450     facetT *f= facet.getFacetT();
00451     QhullRidgeSet rs= facet.ridges();
00452     if(!rs.isEmpty()){
00453         if(pr.run_id!=UsingLibQhull::NOqhRunId){
00454             UsingLibQhull q(pr.run_id);
00455             // No calls to libqhull
00456             if(f->visible && qh NEWfacets){
00457                 os << "    - ridges(ids may be garbage):";
00458                 for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
00459                     QhullRidge r= *i;
00460                     os << " r" << r.id();
00461                 }
00462                 os << endl;
00463             }else{
00464                 os << "    - ridges:" << endl;
00465             }
00466         }else{
00467             os << "    - ridges:" << endl;
00468         }
00469 
00470         // Keep track of printed ridges
00471         for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
00472             QhullRidge r= *i;
00473             r.getRidgeT()->seen= false;
00474         }
00475         int ridgeCount= 0;
00476         if(facet.dimension()==3){
00477             for(QhullRidge r= rs.first(); !r.getRidgeT()->seen; r= r.nextRidge3d(facet)){
00478                 r.getRidgeT()->seen= true;
00479                 os << r.print(pr.run_id);
00480                 ++ridgeCount;
00481                 if(!r.hasNextRidge3d(facet)){
00482                     break;
00483                 }
00484             }
00485         }else {
00486             QhullFacetSet ns(facet.neighborFacets());
00487             for(QhullFacetSet::iterator i=ns.begin(); i!=ns.end(); ++i){
00488                 QhullFacet neighbor= *i;
00489                 QhullRidgeSet nrs(neighbor.ridges());
00490                 for(QhullRidgeSet::iterator j=nrs.begin(); j!=nrs.end(); ++j){
00491                     QhullRidge r= *j;
00492                     if(r.otherFacet(neighbor)==facet){
00493                         r.getRidgeT()->seen= true;
00494                         os << r.print(pr.run_id);
00495                         ridgeCount++;
00496                     }
00497                 }
00498             }
00499         }
00500         if(ridgeCount!=rs.count()){
00501             os << "     - all ridges:";
00502             for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
00503                 QhullRidge r= *i;
00504                 os << " r" << r.id();
00505             }
00506             os << endl;
00507         }
00508         for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
00509             QhullRidge r= *i;
00510             if(!r.getRidgeT()->seen){
00511                 os << r.print(pr.run_id);
00512             }
00513         }
00514     }
00515     return os;
00516 }//operator<< PrintRidges
00517 
00518 // "No conversion" error if defined inline
00519 ostream &
00520 operator<<(ostream &os, QhullFacet &f)
00521 {
00522     os << f.print(UsingLibQhull::NOqhRunId);
00523     return os;
00524 }//<< QhullFacet


libqhull-ours
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:11