Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F122203269
QhullFacet.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Jul 16, 14:34
Size
15 KB
Mime Type
text/x-c
Expires
Fri, Jul 18, 14:34 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
27449377
Attached To
rCADDMESH CADD_mesher
QhullFacet.cpp
View Options
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2011/qhull/src/libqhullpcpp/QhullFacet.cpp#2 $$Change: 1810 $
** $DateTime: 2015/01/17 18:28:15 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
#include "QhullError.h"
#include "QhullSet.h"
#include "QhullPoint.h"
#include "QhullPointSet.h"
#include "QhullRidge.h"
#include "QhullFacet.h"
#include "QhullFacetSet.h"
#include "QhullVertex.h"
#include <ostream>
using std::endl;
using std::string;
using std::vector;
using std::ostream;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//class statics
facetT QhullFacet::
s_empty_facet= {0,0,0,0,{0},
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0};
#//GetSet
int QhullFacet::
dimension() const
{
if(qh_facet->ridges){
setT *s= qh_facet->ridges;
ridgeT *r= reinterpret_cast<ridgeT *>(SETfirst_(s));
return r ? QhullSetBase::count(r->vertices)+1 : 0;
}else{
return QhullSetBase::count(qh_facet->vertices);
}
}//dimension
//! Return voronoi center or facet centrum. Derived from qh_printcenter [io.c]
//! printFormat=qh_PRINTtriangles if return centrum of a Delaunay facet
//! Sets center if needed
//! Code duplicated for PrintCenter and getCenter
//! .empty() if none or qh_INFINITE
QhullPoint QhullFacet::
getCenter(int qhRunId, qh_PRINT printFormat)
{
UsingLibQhull q(qhRunId);
if(qh CENTERtype==qh_ASvoronoi){
if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh ATinfinity){
if(!qh_facet->center){
int exitCode = setjmp(qh errexit);
if(!exitCode){ // no object creation -- destructors skipped on longjmp()
qh_facet->center= qh_facetcenter(qh_facet->vertices);
}
q.maybeThrowQhullMessage(exitCode);
}
return QhullPoint(qh hull_dim-1, qh_facet->center);
}
}else if(qh CENTERtype==qh_AScentrum){
volatile int numCoords= qh hull_dim;
if(printFormat==qh_PRINTtriangles && qh DELAUNAY){
numCoords--;
}
if(!qh_facet->center){
int exitCode = setjmp(qh errexit);
if(!exitCode){ // no object creation -- destructors skipped on longjmp()
qh_facet->center= qh_getcentrum(getFacetT());
}
q.maybeThrowQhullMessage(exitCode);
}
return QhullPoint(numCoords, qh_facet->center);
}
return QhullPoint();
}//getCenter
//! Return innerplane clearly below the vertices
//! from io.c[qh_PRINTinner]
QhullHyperplane QhullFacet::
innerplane(int qhRunId) const{
UsingLibQhull q(qhRunId);
realT inner;
// Does not error
qh_outerinner(const_cast<facetT *>(getFacetT()), NULL, &inner);
QhullHyperplane h= hyperplane();
h.setOffset(h.offset()-inner); //inner is negative
return h;
}//innerplane
//! Return outerplane clearly above all points
//! from io.c[qh_PRINTouter]
QhullHyperplane QhullFacet::
outerplane(int qhRunId) const{
UsingLibQhull q(qhRunId);
realT outer;
// Does not error
qh_outerinner(const_cast<facetT *>(getFacetT()), &outer, NULL);
QhullHyperplane h= hyperplane();
h.setOffset(h.offset()-outer); //outer is positive
return h;
}//outerplane
//! Set by qh_triangulate for option 'Qt'.
//! Errors if tricoplanar and facetArea() or qh_getarea() called first.
QhullFacet QhullFacet::
tricoplanarOwner() const
{
if(qh_facet->tricoplanar){
if(qh_facet->isarea){
throw QhullError(10018, "Qhull error: facetArea() or qh_getarea() previously called. triCoplanarOwner() is not available.");
}
return qh_facet->f.triowner;
}
return 0; // FIXUP QH11009 Should false be the NULL facet or empty facet
}//tricoplanarOwner
QhullPoint QhullFacet::
voronoiVertex(int qhRunId)
{
if(
#if qh_QHpointer
!qh_qh ||
#endif
qh CENTERtype!=qh_ASvoronoi){
throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
}
return getCenter(qhRunId);
}//voronoiVertex
#//Value
//! Disables tricoplanarOwner()
double QhullFacet::
facetArea(int qhRunId)
{
if(!qh_facet->isarea){
UsingLibQhull q(qhRunId);
int exitCode = setjmp(qh errexit);
if(!exitCode){ // no object creation -- destructors skipped on longjmp()
qh_facet->f.area= qh_facetarea(qh_facet);
qh_facet->isarea= True;
}
q.maybeThrowQhullMessage(exitCode);
}
return qh_facet->f.area;
}//facetArea
#//Foreach
QhullPointSet QhullFacet::
coplanarPoints() const
{
return QhullPointSet(dimension(), qh_facet->coplanarset);
}//coplanarPoints
QhullFacetSet QhullFacet::
neighborFacets() const
{
return QhullFacetSet(qh_facet->neighbors);
}//neighborFacets
QhullPointSet QhullFacet::
outsidePoints() const
{
return QhullPointSet(dimension(), qh_facet->outsideset);
}//outsidePoints
QhullRidgeSet QhullFacet::
ridges() const
{
return QhullRidgeSet(qh_facet->ridges);
}//ridges
QhullVertexSet QhullFacet::
vertices() const
{
return QhullVertexSet(qh_facet->vertices);
}//vertices
}//namespace orgQhull
#//operator<<
using std::ostream;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetSet;
using orgQhull::QhullPoint;
using orgQhull::QhullPointSet;
using orgQhull::QhullRidge;
using orgQhull::QhullRidgeSet;
using orgQhull::QhullSetBase;
using orgQhull::QhullVertexSet;
using orgQhull::UsingLibQhull;
ostream &
operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
{
QhullFacet f= *pr.facet;
if(f.getFacetT()==0){ // Special values from set iterator
os << " NULLfacet" << endl;
return os;
}
if(f.getFacetT()==qh_MERGEridge){
os << " MERGEridge" << endl;
return os;
}
if(f.getFacetT()==qh_DUPLICATEridge){
os << " DUPLICATEridge" << endl;
return os;
}
os << f.printHeader(pr.run_id);
if(!f.ridges().isEmpty()){
os << f.printRidges(pr.run_id);
}
return os;
}//operator<< PrintFacet
//! Print Voronoi center or facet centrum to stream. Same as qh_printcenter [io.c]
//! Code duplicated for PrintCenter and getCenter
//! Sets center if needed
ostream &
operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
{
facetT *f= pr.facet->getFacetT();
if(qh CENTERtype!=qh_ASvoronoi && qh CENTERtype!=qh_AScentrum){
return os;
}
if (pr.message){
os << pr.message;
}
int numCoords;
if(qh CENTERtype==qh_ASvoronoi){
numCoords= qh hull_dim-1;
if(!f->normal || !f->upperdelaunay || !qh ATinfinity){
if(!f->center){
f->center= qh_facetcenter(f->vertices);
}
for(int k=0; k<numCoords; k++){
os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
}
}else{
for(int k=0; k<numCoords; k++){
os << qh_INFINITE << " "; // FIXUP QH11010 qh_REAL_1
}
}
}else{ // qh CENTERtype==qh_AScentrum
numCoords= qh hull_dim;
if(pr.print_format==qh_PRINTtriangles && qh DELAUNAY){
numCoords--;
}
if(!f->center){
f->center= qh_getcentrum(f);
}
for(int k=0; k<numCoords; k++){
os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
}
}
if(pr.print_format==qh_PRINTgeom && numCoords==2){
os << " 0";
}
os << endl;
return os;
}//operator<< PrintCenter
//! Print flags for facet to stream. Space prefix. From qh_printfacetheader [io.c]
ostream &
operator<<(ostream &os, const QhullFacet::PrintFlags &p)
{
const facetT *f= p.facet->getFacetT();
if(p.message){
os << p.message;
}
os << (p.facet->isTopOrient() ? " top" : " bottom");
if(p.facet->isSimplicial()){
os << " simplicial";
}
if(p.facet->isTriCoplanar()){
os << " tricoplanar";
}
if(p.facet->isUpperDelaunay()){
os << " upperDelaunay";
}
if(f->visible){
os << " visible";
}
if(f->newfacet){
os << " new";
}
if(f->tested){
os << " tested";
}
if(!f->good){
os << " notG";
}
if(f->seen){
os << " seen";
}
if(f->coplanar){
os << " coplanar";
}
if(f->mergehorizon){
os << " mergehorizon";
}
if(f->keepcentrum){
os << " keepcentrum";
}
if(f->dupridge){
os << " dupridge";
}
if(f->mergeridge && !f->mergeridge2){
os << " mergeridge1";
}
if(f->mergeridge2){
os << " mergeridge2";
}
if(f->newmerge){
os << " newmerge";
}
if(f->flipped){
os << " flipped";
}
if(f->notfurthest){
os << " notfurthest";
}
if(f->degenerate){
os << " degenerate";
}
if(f->redundant){
os << " redundant";
}
os << endl;
return os;
}//operator<< PrintFlags
//! Print header for facet to stream. Space prefix. From qh_printfacetheader [io.c]
ostream &
operator<<(ostream &os, const QhullFacet::PrintHeader &pr)
{
QhullFacet facet= *pr.facet;
facetT *f= facet.getFacetT();
os << "- f" << facet.id() << endl;
os << facet.printFlags(" - flags:");
if(f->isarea){
os << " - area: " << f->f.area << endl; //FIXUP QH11010 2.2g
}else if(qh NEWfacets && f->visible && f->f.replace){
os << " - replacement: f" << f->f.replace->id << endl;
}else if(f->newfacet){
if(f->f.samecycle && f->f.samecycle != f){
os << " - shares same visible/horizon as f" << f->f.samecycle->id << endl;
}
}else if(f->tricoplanar /* !isarea */){
if(f->f.triowner){
os << " - owner of normal & centrum is facet f" << f->f.triowner->id << endl;
}
}else if(f->f.newcycle){
os << " - was horizon to f" << f->f.newcycle->id << endl;
}
if(f->nummerge){
os << " - merges: " << f->nummerge << endl;
}
os << facet.hyperplane().print(" - normal: ", "\n - offset: "); // FIXUP QH11010 %10.7g
if(qh CENTERtype==qh_ASvoronoi || f->center){
os << facet.printCenter(pr.run_id, qh_PRINTfacets, " - center: ");
}
#if qh_MAXoutside
if(f->maxoutside > qh DISTround){
os << " - maxoutside: " << f->maxoutside << endl; //FIXUP QH11010 %10.7g
}
#endif
QhullPointSet ps= facet.outsidePoints();
if(!ps.isEmpty()){
QhullPoint furthest= ps.last();
if (ps.size() < 6) {
os << " - outside set(furthest p" << furthest.id(pr.run_id) << "):" << endl;
for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
QhullPoint p= *i;
os << p.print(pr.run_id, " ");
}
}else if(ps.size()<21){
os << ps.print(pr.run_id, " - outside set:");
}else{
os << " - outside set: " << ps.size() << " points.";
os << furthest.print(pr.run_id, " Furthest");
}
#if !qh_COMPUTEfurthest
os << " - furthest distance= " << f->furthestdist << endl; //FIXUP QH11010 %2.2g
#endif
}
QhullPointSet cs= facet.coplanarPoints();
if(!cs.isEmpty()){
QhullPoint furthest= cs.last();
if (cs.size() < 6) {
os << " - coplanar set(furthest p" << furthest.id(pr.run_id) << "):" << endl;
for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
QhullPoint p= *i;
os << p.print(pr.run_id, " ");
}
}else if(cs.size()<21){
os << cs.print(pr.run_id, " - coplanar set:");
}else{
os << " - coplanar set: " << cs.size() << " points.";
os << furthest.print(pr.run_id, " Furthest");
}
zinc_(Zdistio);
double d= facet.distance(furthest);
os << " furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
}
QhullVertexSet vs= facet.vertices();
if(!vs.isEmpty()){
os << vs.print(pr.run_id, " - vertices:");
}
QhullFacetSet fs= facet.neighborFacets();
fs.selectAll();
if(!fs.isEmpty()){
os << fs.printIdentifiers(" - neighboring facets:");
}
return os;
}//operator<< PrintHeader
//! Print ridges of facet to stream. Same as qh_printfacetridges [io.c]
//! If qhRunId==UsingLibQhull::NOqhRunId, does not use qh
ostream &
operator<<(ostream &os, const QhullFacet::PrintRidges &pr)
{
const QhullFacet facet= *pr.facet;
facetT *f= facet.getFacetT();
QhullRidgeSet rs= facet.ridges();
if(!rs.isEmpty()){
if(pr.run_id!=UsingLibQhull::NOqhRunId){
UsingLibQhull q(pr.run_id);
// No calls to libqhull
if(f->visible && qh NEWfacets){
os << " - ridges(ids may be garbage):";
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
os << " r" << r.id();
}
os << endl;
}else{
os << " - ridges:" << endl;
}
}else{
os << " - ridges:" << endl;
}
// Keep track of printed ridges
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
r.getRidgeT()->seen= false;
}
int ridgeCount= 0;
if(facet.dimension()==3){
for(QhullRidge r= rs.first(); !r.getRidgeT()->seen; r= r.nextRidge3d(facet)){
r.getRidgeT()->seen= true;
os << r.print(pr.run_id);
++ridgeCount;
if(!r.hasNextRidge3d(facet)){
break;
}
}
}else {
QhullFacetSet ns(facet.neighborFacets());
for(QhullFacetSet::iterator i=ns.begin(); i!=ns.end(); ++i){
QhullFacet neighbor= *i;
QhullRidgeSet nrs(neighbor.ridges());
for(QhullRidgeSet::iterator j=nrs.begin(); j!=nrs.end(); ++j){
QhullRidge r= *j;
if(r.otherFacet(neighbor)==facet){
r.getRidgeT()->seen= true;
os << r.print(pr.run_id);
ridgeCount++;
}
}
}
}
if(ridgeCount!=rs.count()){
os << " - all ridges:";
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
os << " r" << r.id();
}
os << endl;
}
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
if(!r.getRidgeT()->seen){
os << r.print(pr.run_id);
}
}
}
return os;
}//operator<< PrintRidges
// "No conversion" error if defined inline
ostream &
operator<<(ostream &os, QhullFacet &f)
{
os << f.print(UsingLibQhull::NOqhRunId);
return os;
}//<< QhullFacet
Event Timeline
Log In to Comment