Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F81386100
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
Thu, Sep 5, 17:23
Size
15 KB
Mime Type
text/x-c
Expires
Sat, Sep 7, 17:23 (2 d)
Engine
blob
Format
Raw Data
Handle
20557907
Attached To
rCADDMESH CADD_mesher
QhullFacet.cpp
View Options
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullPointSet.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullFacetSet.h"
#include "libqhullcpp/QhullVertex.h"
#include <ostream>
using std::endl;
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 {
#//!\name Class objects
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};
#//!\name Constructors
QhullFacet::
QhullFacet(const Qhull &q)
: qh_facet(&s_empty_facet)
, qh_qh(q.qh())
{
}
QhullFacet::
QhullFacet(const Qhull &q, facetT *f)
: qh_facet(f ? f : &s_empty_facet)
, qh_qh(q.qh())
{
}
#//!\name GetSet
//! Return voronoi center or facet centrum. Derived from qh_printcenter [io_r.c]
//! if printFormat=qh_PRINTtriangles and qh.DELAUNAY, returns centrum of a Delaunay facet
//! Sets center if needed
//! Code duplicated for PrintCenter and getCenter
//! Returns QhullPoint() if none or qh_INFINITE
QhullPoint QhullFacet::
getCenter(qh_PRINT printFormat)
{
if(!qh_qh){
// returns QhullPoint()
}else if(qh_qh->CENTERtype==qh_ASvoronoi){
if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh_qh->ATinfinity){
if(!qh_facet->center){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_facet->center= qh_facetcenter(qh_qh, qh_facet->vertices);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return QhullPoint(qh_qh, qh_qh->hull_dim-1, qh_facet->center);
}
}else if(qh_qh->CENTERtype==qh_AScentrum){
volatile int numCoords= qh_qh->hull_dim;
if(printFormat==qh_PRINTtriangles && qh_qh->DELAUNAY){
numCoords--;
}
if(!qh_facet->center){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_facet->center= qh_getcentrum(qh_qh, getFacetT());
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return QhullPoint(qh_qh, numCoords, qh_facet->center);
}
return QhullPoint();
}//getCenter
//! Return innerplane clearly below the vertices
//! from io_r.c[qh_PRINTinner]
QhullHyperplane QhullFacet::
innerplane() const{
QhullHyperplane h;
if(qh_qh){
realT inner;
// Does not error, TRY_QHULL_ not needed
qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), NULL, &inner);
h= hyperplane();
h.setOffset(h.offset()-inner); //inner is negative
}
return h;
}//innerplane
//! Return outerplane clearly above all points
//! from io_r.c[qh_PRINTouter]
QhullHyperplane QhullFacet::
outerplane() const{
QhullHyperplane h;
if(qh_qh){
realT outer;
// Does not error, TRY_QHULL_ not needed
qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), &outer, NULL);
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 QhullFacet(qh_qh, qh_facet->f.triowner);
}
return QhullFacet(qh_qh);
}//tricoplanarOwner
QhullPoint QhullFacet::
voronoiVertex()
{
if(qh_qh && qh_qh->CENTERtype!=qh_ASvoronoi){
throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
}
return getCenter();
}//voronoiVertex
#//!\name Value
//! Disables tricoplanarOwner()
double QhullFacet::
facetArea()
{
if(qh_qh && !qh_facet->isarea){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_facet->f.area= qh_facetarea(qh_qh, qh_facet);
qh_facet->isarea= True;
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return qh_facet->f.area;
}//facetArea
#//!\name Foreach
QhullPointSet QhullFacet::
coplanarPoints() const
{
return QhullPointSet(qh_qh, qh_facet->coplanarset);
}//coplanarPoints
QhullFacetSet QhullFacet::
neighborFacets() const
{
return QhullFacetSet(qh_qh, qh_facet->neighbors);
}//neighborFacets
QhullPointSet QhullFacet::
outsidePoints() const
{
return QhullPointSet(qh_qh, qh_facet->outsideset);
}//outsidePoints
QhullRidgeSet QhullFacet::
ridges() const
{
return QhullRidgeSet(qh_qh, qh_facet->ridges);
}//ridges
QhullVertexSet QhullFacet::
vertices() const
{
return QhullVertexSet(qh_qh, qh_facet->vertices);
}//vertices
}//namespace orgQhull
#//!\name 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;
ostream &
operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
{
os << pr.message;
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();
if(!f.ridges().isEmpty()){
os << f.printRidges();
}
return os;
}//operator<< PrintFacet
//! Print Voronoi center or facet centrum to stream. Same as qh_printcenter [_r.]
//! Code duplicated for PrintCenter and getCenter
//! Sets center if needed
ostream &
operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
{
facetT *f= pr.facet->getFacetT();
if(pr.facet->qh()->CENTERtype!=qh_ASvoronoi && pr.facet->qh()->CENTERtype!=qh_AScentrum){
return os;
}
if (pr.message){
os << pr.message;
}
int numCoords;
if(pr.facet->qh()->CENTERtype==qh_ASvoronoi){
numCoords= pr.facet->qh()->hull_dim-1;
if(!f->normal || !f->upperdelaunay || !pr.facet->qh()->ATinfinity){
if(!f->center){
f->center= qh_facetcenter(pr.facet->qh(), 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= pr.facet->qh()->hull_dim;
if(pr.print_format==qh_PRINTtriangles && pr.facet->qh()->DELAUNAY){
numCoords--;
}
if(!f->center){
f->center= qh_getcentrum(pr.facet->qh(), 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_r.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_r.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(pr.facet->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(pr.facet->qh()->CENTERtype==qh_ASvoronoi || f->center){
os << facet.printCenter(qh_PRINTfacets, " - center: ");
}
#if qh_MAXoutside
if(f->maxoutside > pr.facet->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() << "):" << endl;
for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
QhullPoint p= *i;
os << p.print(" ");
}
}else if(ps.size()<21){
os << ps.print(" - outside set:");
}else{
os << " - outside set: " << ps.size() << " points.";
os << furthest.print(" 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() << "):" << endl;
for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
QhullPoint p= *i;
os << p.print(" ");
}
}else if(cs.size()<21){
os << cs.print(" - coplanar set:");
}else{
os << " - coplanar set: " << cs.size() << " points.";
os << furthest.print(" Furthest");
}
// FIXUP QH11027 Can/should zinc_(Zdistio) be called from C++ interface
double d= facet.distance(furthest);
os << " furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
}
QhullVertexSet vs= facet.vertices();
if(!vs.isEmpty()){
os << vs.print(" - 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_r.c]
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(f->visible && pr.facet->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;
}
// 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("");
++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("");
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("");
}
}
}
return os;
}//operator<< PrintRidges
// "No conversion" error if defined inline
ostream &
operator<<(ostream &os, QhullFacet &f)
{
os << f.print("");
return os;
}//<< QhullFacet
Event Timeline
Log In to Comment