Refactor folder (#10475)

Move many third-party components' source codes from the src folder to a new folder called deps_src. The goal is to make the code structure clearer and easier to navigate.
This commit is contained in:
SoftFever
2025-08-22 20:02:26 +08:00
committed by GitHub
parent 3808f7eb28
commit 883607e1d4
2083 changed files with 1163 additions and 19503 deletions

View File

@@ -0,0 +1,198 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.cpp#4 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/Coordinates.h"
#include "libqhullcpp/functionObjects.h"
#include "libqhullcpp/QhullError.h"
#include <iostream>
#include <iterator>
#include <algorithm>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//! Coordinates -- vector of coordT (normally double)
#//!\name Constructor
#//!\name Element access
// Inefficient without result-value-optimization or implicitly shared object
Coordinates Coordinates::
mid(countT idx, countT length) const
{
countT newLength= length;
if(length<0 || idx+length > count()){
newLength= count()-idx;
}
Coordinates result;
if(newLength>0){
std::copy(begin()+idx, begin()+(idx+newLength), std::back_inserter(result));
}
return result;
}//mid
coordT Coordinates::
value(countT idx, const coordT &defaultValue) const
{
return ((idx < 0 || idx >= count()) ? defaultValue : (*this)[idx]);
}//value
#//!\name GetSet
Coordinates Coordinates::
operator+(const Coordinates &other) const
{
Coordinates result(*this);
std::copy(other.begin(), other.end(), std::back_inserter(result));
return result;
}//operator+
Coordinates & Coordinates::
operator+=(const Coordinates &other)
{
if(&other==this){
Coordinates clone(other);
std::copy(clone.begin(), clone.end(), std::back_inserter(*this));
}else{
std::copy(other.begin(), other.end(), std::back_inserter(*this));
}
return *this;
}//operator+=
#//!\name Read-write
void Coordinates::
append(int pointDimension, coordT *c)
{
if(c){
coordT *p= c;
for(int i= 0; i<pointDimension; ++i){
coordinate_array.push_back(*p++);
}
}
}//append dim coordT
coordT Coordinates::
takeAt(countT idx)
{
coordT c= at(idx);
erase(begin()+idx);
return c;
}//takeAt
coordT Coordinates::
takeLast()
{
coordT c= last();
removeLast();
return c;
}//takeLast
void Coordinates::
swap(countT idx, countT other)
{
coordT c= at(idx);
at(idx)= at(other);
at(other)= c;
}//swap
#//!\name Search
bool Coordinates::
contains(const coordT &t) const
{
CoordinatesIterator i(*this);
return i.findNext(t);
}//contains
countT Coordinates::
count(const coordT &t) const
{
CoordinatesIterator i(*this);
countT result= 0;
while(i.findNext(t)){
++result;
}
return result;
}//count
countT Coordinates::
indexOf(const coordT &t, countT from) const
{
if(from<0){
from += count();
if(from<0){
from= 0;
}
}
if(from<count()){
const_iterator i= begin()+from;
while(i!=constEnd()){
if(*i==t){
return (static_cast<countT>(i-begin())); // WARN64 coordinate index
}
++i;
}
}
return -1;
}//indexOf
countT Coordinates::
lastIndexOf(const coordT &t, countT from) const
{
if(from<0){
from += count();
}else if(from>=count()){
from= count()-1;
}
if(from>=0){
const_iterator i= begin()+from+1;
while(i-- != constBegin()){
if(*i==t){
return (static_cast<countT>(i-begin())); // WARN64 coordinate index
}
}
}
return -1;
}//lastIndexOf
void Coordinates::
removeAll(const coordT &t)
{
MutableCoordinatesIterator i(*this);
while(i.findNext(t)){
i.remove();
}
}//removeAll
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::istream;
using std::ostream;
using std::string;
using std::ws;
using orgQhull::Coordinates;
ostream &
operator<<(ostream &os, const Coordinates &cs)
{
Coordinates::const_iterator c= cs.begin();
for(countT i=cs.count(); i--; ){
os << *c++ << " ";
}
return os;
}//operator<<

View File

@@ -0,0 +1,303 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.h#6 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHCOORDINATES_H
#define QHCOORDINATES_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullIterator.h"
#include <cstddef> // ptrdiff_t, size_t
#include <ostream>
// Requires STL vector class. Can use with another vector class such as QList.
#include <vector>
namespace orgQhull {
#//!\name Defined here
//! An std::vector of point coordinates independent of dimension
//! Used by PointCoordinates for RboxPoints and by Qhull for feasiblePoint
//! A QhullPoint refers to previously allocated coordinates
class Coordinates;
class MutableCoordinatesIterator;
class Coordinates {
private:
#//!\name Fields
std::vector<coordT> coordinate_array;
public:
#//!\name Subtypes
class const_iterator;
class iterator;
typedef iterator Iterator;
typedef const_iterator ConstIterator;
typedef coordT value_type;
typedef const value_type *const_pointer;
typedef const value_type & const_reference;
typedef value_type * pointer;
typedef value_type & reference;
typedef ptrdiff_t difference_type;
typedef countT size_type;
#//!\name Construct
Coordinates() {};
explicit Coordinates(const std::vector<coordT> &other) : coordinate_array(other) {}
Coordinates(const Coordinates &other) : coordinate_array(other.coordinate_array) {}
Coordinates & operator=(const Coordinates &other) { coordinate_array= other.coordinate_array; return *this; }
Coordinates & operator=(const std::vector<coordT> &other) { coordinate_array= other; return *this; }
~Coordinates() {}
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<coordT> toStdVector() const { return coordinate_array; }
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
countT count() const { return static_cast<countT>(size()); }
coordT * data() { return isEmpty() ? 0 : &at(0); }
const coordT * data() const { return const_cast<const pointT*>(isEmpty() ? 0 : &at(0)); }
bool isEmpty() const { return coordinate_array.empty(); }
bool operator==(const Coordinates &other) const { return coordinate_array==other.coordinate_array; }
bool operator!=(const Coordinates &other) const { return coordinate_array!=other.coordinate_array; }
size_t size() const { return coordinate_array.size(); }
#//!\name Element access
coordT & at(countT idx) { return coordinate_array.at(idx); }
const coordT & at(countT idx) const { return coordinate_array.at(idx); }
coordT & back() { return coordinate_array.back(); }
const coordT & back() const { return coordinate_array.back(); }
coordT & first() { return front(); }
const coordT & first() const { return front(); }
coordT & front() { return coordinate_array.front(); }
const coordT & front() const { return coordinate_array.front(); }
coordT & last() { return back(); }
const coordT & last() const { return back(); }
Coordinates mid(countT idx, countT length= -1) const; //!<\todo countT -1 indicates
coordT & operator[](countT idx) { return coordinate_array.operator[](idx); }
const coordT & operator[](countT idx) const { return coordinate_array.operator[](idx); }
coordT value(countT idx, const coordT &defaultValue) const;
#//!\name Iterator
iterator begin() { return iterator(coordinate_array.begin()); }
const_iterator begin() const { return const_iterator(coordinate_array.begin()); }
const_iterator constBegin() const { return begin(); }
const_iterator constEnd() const { return end(); }
iterator end() { return iterator(coordinate_array.end()); }
const_iterator end() const { return const_iterator(coordinate_array.end()); }
#//!\name GetSet
Coordinates operator+(const Coordinates &other) const;
#//!\name Modify
void append(int pointDimension, coordT *c);
void append(const coordT &c) { push_back(c); }
void clear() { coordinate_array.clear(); }
iterator erase(iterator idx) { return iterator(coordinate_array.erase(idx.base())); }
iterator erase(iterator beginIterator, iterator endIterator) { return iterator(coordinate_array.erase(beginIterator.base(), endIterator.base())); }
void insert(countT before, const coordT &c) { insert(begin()+before, c); }
iterator insert(iterator before, const coordT &c) { return iterator(coordinate_array.insert(before.base(), c)); }
void move(countT from, countT to) { insert(to, takeAt(from)); }
Coordinates & operator+=(const Coordinates &other);
Coordinates & operator+=(const coordT &c) { append(c); return *this; }
Coordinates & operator<<(const Coordinates &other) { return *this += other; }
Coordinates & operator<<(const coordT &c) { return *this += c; }
void pop_back() { coordinate_array.pop_back(); }
void pop_front() { removeFirst(); }
void prepend(const coordT &c) { insert(begin(), c); }
void push_back(const coordT &c) { coordinate_array.push_back(c); }
void push_front(const coordT &c) { insert(begin(), c); }
//removeAll below
void removeAt(countT idx) { erase(begin()+idx); }
void removeFirst() { erase(begin()); }
void removeLast() { erase(--end()); }
void replace(countT idx, const coordT &c) { (*this)[idx]= c; }
void reserve(countT i) { coordinate_array.reserve(i); }
void swap(countT idx, countT other);
coordT takeAt(countT idx);
coordT takeFirst() { return takeAt(0); }
coordT takeLast();
#//!\name Search
bool contains(const coordT &t) const;
countT count(const coordT &t) const;
countT indexOf(const coordT &t, countT from = 0) const;
countT lastIndexOf(const coordT &t, countT from = -1) const;
void removeAll(const coordT &t);
#//!\name Coordinates::iterator -- from QhullPoints, forwarding to coordinate_array
// before const_iterator for conversion with comparison operators
// Reviewed corelib/tools/qlist.h and corelib/tools/qvector.h w/o QT_STRICT_ITERATORS
class iterator {
private:
std::vector<coordT>::iterator i;
friend class const_iterator;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef coordT value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef ptrdiff_t difference_type;
iterator() {}
iterator(const iterator &other) { i= other.i; }
explicit iterator(const std::vector<coordT>::iterator &vi) { i= vi; }
iterator & operator=(const iterator &other) { i= other.i; return *this; }
std::vector<coordT>::iterator &base() { return i; }
coordT & operator*() const { return *i; }
// No operator->() when the base type is double
coordT & operator[](countT idx) const { return i[idx]; }
bool operator==(const iterator &other) const { return i==other.i; }
bool operator!=(const iterator &other) const { return i!=other.i; }
bool operator<(const iterator &other) const { return i<other.i; }
bool operator<=(const iterator &other) const { return i<=other.i; }
bool operator>(const iterator &other) const { return i>other.i; }
bool operator>=(const iterator &other) const { return i>=other.i; }
// reinterpret_cast to break circular dependency
bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast<const iterator &>(other); }
bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast<const iterator &>(other); }
bool operator<(const Coordinates::const_iterator &other) const { return *this<reinterpret_cast<const iterator &>(other); }
bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast<const iterator &>(other); }
bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast<const iterator &>(other); }
bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast<const iterator &>(other); }
iterator & operator++() { ++i; return *this; }
iterator operator++(int) { return iterator(i++); }
iterator & operator--() { --i; return *this; }
iterator operator--(int) { return iterator(i--); }
iterator & operator+=(countT idx) { i += idx; return *this; }
iterator & operator-=(countT idx) { i -= idx; return *this; }
iterator operator+(countT idx) const { return iterator(i+idx); }
iterator operator-(countT idx) const { return iterator(i-idx); }
difference_type operator-(iterator other) const { return i-other.i; }
};//Coordinates::iterator
#//!\name Coordinates::const_iterator
class const_iterator {
private:
std::vector<coordT>::const_iterator i;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef coordT value_type;
typedef const value_type *pointer;
typedef const value_type &reference;
typedef ptrdiff_t difference_type;
const_iterator() {}
const_iterator(const const_iterator &other) { i= other.i; }
const_iterator(const iterator &o) : i(o.i) {}
explicit const_iterator(const std::vector<coordT>::const_iterator &vi) { i= vi; }
const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
const coordT & operator*() const { return *i; }
// No operator->() when the base type is double
const coordT & operator[](countT idx) const { return i[idx]; }
bool operator==(const const_iterator &other) const { return i==other.i; }
bool operator!=(const const_iterator &other) const { return i!=other.i; }
bool operator<(const const_iterator &other) const { return i<other.i; }
bool operator<=(const const_iterator &other) const { return i<=other.i; }
bool operator>(const const_iterator &other) const { return i>other.i; }
bool operator>=(const const_iterator &other) const { return i>=other.i; }
const_iterator & operator++() { ++i; return *this; }
const_iterator operator++(int) { return const_iterator(i++); }
const_iterator & operator--() { --i; return *this; }
const_iterator operator--(int) { return const_iterator(i--); }
const_iterator & operator+=(countT idx) { i += idx; return *this; }
const_iterator & operator-=(countT idx) { i -= idx; return *this; }
const_iterator operator+(countT idx) const { return const_iterator(i+idx); }
const_iterator operator-(countT idx) const { return const_iterator(i-idx); }
difference_type operator-(const_iterator other) const { return i-other.i; }
};//Coordinates::const_iterator
};//Coordinates
//class CoordinatesIterator
//QHULL_DECLARE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
class CoordinatesIterator
{
typedef Coordinates::const_iterator const_iterator;
private:
const Coordinates * c;
const_iterator i;
public:
CoordinatesIterator(const Coordinates &container): c(&container), i(c->constBegin()) {}
CoordinatesIterator &operator=(const Coordinates &container) { c= &container; i= c->constBegin(); return *this; }
~CoordinatesIterator() {}
bool findNext(const coordT &t) { while (i != c->constEnd()) if(*i++ == t){ return true;} return false; }
bool findPrevious(const coordT &t) { while (i != c->constBegin())if (*(--i) == t){ return true;} return false; }
bool hasNext() const { return i != c->constEnd(); }
bool hasPrevious() const { return i != c->constBegin(); }
const coordT & next() { return *i++; }
const coordT & previous() { return *--i; }
const coordT & peekNext() const { return *i; }
const coordT & peekPrevious() const { const_iterator p= i; return *--p; }
void toFront() { i= c->constBegin(); }
void toBack() { i= c->constEnd(); }
};//CoordinatesIterator
//class MutableCoordinatesIterator
//QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
class MutableCoordinatesIterator
{
typedef Coordinates::iterator iterator;
typedef Coordinates::const_iterator const_iterator;
private:
Coordinates * c;
iterator i;
iterator n;
bool item_exists() const { return const_iterator(n) != c->constEnd(); }
public:
MutableCoordinatesIterator(Coordinates &container) : c(&container) { i= c->begin(); n= c->end(); }
MutableCoordinatesIterator &operator=(Coordinates &container) { c= &container; i= c->begin(); n= c->end(); return *this; }
~MutableCoordinatesIterator() {}
bool findNext(const coordT &t) { while(c->constEnd()!=const_iterator(n= i)){ if(*i++==t){ return true;}} return false; }
bool findPrevious(const coordT &t) { while(c->constBegin()!=const_iterator(i)){ if(*(n= --i)== t){ return true;}} n= c->end(); return false; }
bool hasNext() const { return (c->constEnd()!=const_iterator(i)); }
bool hasPrevious() const { return (c->constBegin()!=const_iterator(i)); }
void insert(const coordT &t) { n= i= c->insert(i, t); ++i; }
coordT & next() { n= i++; return *n; }
coordT & peekNext() const { return *i; }
coordT & peekPrevious() const { iterator p= i; return *--p; }
coordT & previous() { n= --i; return *n; }
void remove() { if(c->constEnd()!=const_iterator(n)){ i= c->erase(n); n= c->end();} }
void setValue(const coordT &t) const { if(c->constEnd()!=const_iterator(n)){ *n= t;} }
void toFront() { i= c->begin(); n= c->end(); }
void toBack() { i= c->end(); n= i; }
coordT & value() { QHULL_ASSERT(item_exists()); return *n; }
const coordT & value() const { QHULL_ASSERT(item_exists()); return *n; }
};//MutableCoordinatesIterator
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c);
#endif // QHCOORDINATES_H

View File

@@ -0,0 +1,348 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/PointCoordinates.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullPoint.h"
#include <iterator>
#include <iostream>
using std::istream;
using std::string;
using std::ws;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//! PointCoordinates -- vector of PointCoordinates
#//!\name Constructors
PointCoordinates::
PointCoordinates()
: QhullPoints()
, point_coordinates()
, describe_points()
{
}
PointCoordinates::
PointCoordinates(const std::string &aComment)
: QhullPoints()
, point_coordinates()
, describe_points(aComment)
{
}
PointCoordinates::
PointCoordinates(int pointDimension, const std::string &aComment)
: QhullPoints()
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
}
//! Qhull and QhullQh constructors are the same
PointCoordinates::
PointCoordinates(const Qhull &q)
: QhullPoints(q)
, point_coordinates()
, describe_points()
{
}
PointCoordinates::
PointCoordinates(const Qhull &q, const std::string &aComment)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
}
PointCoordinates::
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
}
PointCoordinates::
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
append(coordinatesCount, c);
}
PointCoordinates::
PointCoordinates(QhullQh *qqh)
: QhullPoints(qqh)
, point_coordinates()
, describe_points()
{
}
PointCoordinates::
PointCoordinates(QhullQh *qqh, const std::string &aComment)
: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
}
PointCoordinates::
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment)
: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
}
PointCoordinates::
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
append(coordinatesCount, c);
}
PointCoordinates::
PointCoordinates(const PointCoordinates &other)
: QhullPoints(other)
, point_coordinates(other.point_coordinates)
, describe_points(other.describe_points)
{
makeValid(); // Update point_first and point_end
}
PointCoordinates & PointCoordinates::
operator=(const PointCoordinates &other)
{
QhullPoints::operator=(other);
point_coordinates= other.point_coordinates;
describe_points= other.describe_points;
makeValid(); // Update point_first and point_end
return *this;
}//operator=
PointCoordinates::
~PointCoordinates()
{ }
#//!\name GetSet
void PointCoordinates::
checkValid() const
{
if(getCoordinates().data()!=data()
|| getCoordinates().count()!=coordinateCount()){
throw QhullError(10060, "Qhull error: first point (%x) is not PointCoordinates.data() or count (%d) is not PointCoordinates.count (%d)", coordinateCount(), getCoordinates().count(), 0.0, data());
}
}//checkValid
void PointCoordinates::
setDimension(int i)
{
if(i<0){
throw QhullError(10062, "Qhull error: can not set PointCoordinates dimension to %d", i);
}
int currentDimension=QhullPoints::dimension();
if(currentDimension!=0 && i!=currentDimension){
throw QhullError(10063, "Qhull error: can not change PointCoordinates dimension (from %d to %d)", currentDimension, i);
}
QhullPoints::setDimension(i);
}//setDimension
#//!\name Foreach
Coordinates::ConstIterator PointCoordinates::
beginCoordinates(countT pointIndex) const
{
return point_coordinates.begin()+indexOffset(pointIndex);
}
Coordinates::Iterator PointCoordinates::
beginCoordinates(countT pointIndex)
{
return point_coordinates.begin()+indexOffset(pointIndex);
}
#//!\name Methods
void PointCoordinates::
append(countT coordinatesCount, const coordT *c)
{
if(coordinatesCount<=0){
return;
}
if(includesCoordinates(c)){
throw QhullError(10065, "Qhull error: can not append a subset of PointCoordinates to itself. The coordinates for point %d may move.", indexOf(c, QhullError::NOthrow));
}
reserveCoordinates(coordinatesCount);
std::copy(c, c+coordinatesCount, std::back_inserter(point_coordinates));
makeValid();
}//append coordT
void PointCoordinates::
append(const PointCoordinates &other)
{
setDimension(other.dimension());
append(other.coordinateCount(), other.data());
}//append PointCoordinates
void PointCoordinates::
append(const QhullPoint &p)
{
setDimension(p.dimension());
append(p.dimension(), p.coordinates());
}//append QhullPoint
void PointCoordinates::
appendComment(const std::string &s){
if(char c= s[0] && describe_points.empty()){
if(c=='-' || isdigit(c)){
throw QhullError(10028, "Qhull argument error: comments can not start with a number or minus, %s", 0, 0, 0.0, s.c_str());
}
}
describe_points += s;
}//appendComment
//! Read PointCoordinates from istream. First two numbers are dimension and count. A non-digit starts a rboxCommand.
//! Overwrites describe_points. See qh_readpoints [io.c]
void PointCoordinates::
appendPoints(istream &in)
{
int inDimension;
countT inCount;
in >> ws >> inDimension >> ws;
if(!in.good()){
in.clear();
string remainder;
getline(in, remainder);
throw QhullError(10005, "Qhull error: input did not start with dimension or count -- %s", 0, 0, 0, remainder.c_str());
}
char c= (char)in.peek();
if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
getline(in, describe_points);
in >> ws;
}
in >> inCount >> ws;
if(!in.good()){
in.clear();
string remainder;
getline(in, remainder);
throw QhullError(10009, "Qhull error: input did not start with dimension and count -- %d %s", inDimension, 0, 0, remainder.c_str());
}
c= (char)in.peek();
if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
getline(in, describe_points);
in >> ws;
}
if(inCount<inDimension){ // Count may precede dimension
std::swap(inCount, inDimension);
}
setDimension(inDimension);
reserveCoordinates(inCount*inDimension);
countT coordinatesCount= 0;
while(!in.eof()){
realT p;
in >> p >> ws;
if(in.fail()){
in.clear();
string remainder;
getline(in, remainder);
throw QhullError(10008, "Qhull error: failed to read coordinate %d of point %d\n %s", coordinatesCount % inDimension, coordinatesCount/inDimension, 0, remainder.c_str());
}else{
point_coordinates.push_back(p);
coordinatesCount++;
}
}
if(coordinatesCount != inCount*inDimension){
if(coordinatesCount%inDimension==0){
throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinatesCount/inDimension));
}else{
throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinatesCount%inDimension), coordinatesCount/inDimension);
}
}
makeValid();
}//appendPoints istream
PointCoordinates PointCoordinates::
operator+(const PointCoordinates &other) const
{
PointCoordinates pc= *this;
pc << other;
return pc;
}//operator+
void PointCoordinates::
reserveCoordinates(countT newCoordinates)
{
// vector::reserve is not const
point_coordinates.reserve((countT)point_coordinates.size()+newCoordinates); // WARN64
makeValid();
}//reserveCoordinates
#//!\name Helpers
countT PointCoordinates::
indexOffset(countT i) const {
countT n= i*dimension();
countT coordinatesCount= point_coordinates.count();
if(i<0 || n>coordinatesCount){
throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinatesCount, i);
}
return n;
}
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::Coordinates;
using orgQhull::PointCoordinates;
ostream&
operator<<(ostream &os, const PointCoordinates &p)
{
p.checkValid();
countT count= p.count();
int dimension= p.dimension();
string comment= p.comment();
if(comment.empty()){
os << dimension << endl;
}else{
os << dimension << " " << comment << endl;
}
os << count << endl;
Coordinates::ConstIterator c= p.beginCoordinates();
for(countT i=0; i<count; i++){
for(int j=0; j<dimension; j++){
os << *c++ << " ";
}
os << endl;
}
return os;
}//operator<<

View File

@@ -0,0 +1,161 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHPOINTCOORDINATES_H
#define QHPOINTCOORDINATES_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullPoints.h"
#include "libqhullcpp/Coordinates.h"
#include <ostream>
#include <string>
#ifndef QHULL_NO_STL
#include <vector>
#endif
namespace orgQhull {
#//!\name Defined here
//! QhullPoints with Coordinates and description
//! Inherited by RboxPoints
class PointCoordinates;
class PointCoordinates : public QhullPoints {
private:
#//!\name Fields
Coordinates point_coordinates; //! std::vector of point coordinates
//! may have extraCoordinates()
std::string describe_points; //! Comment describing PointCoordinates
public:
#//!\name Construct
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
//! If Qhull/QhullQh is not initialized, then dimension()==0 PointCoordinates();
PointCoordinates();
explicit PointCoordinates(const std::string &aComment);
PointCoordinates(int pointDimension, const std::string &aComment);
//! Qhull/QhullQh used for dimension() and QhullPoint equality
explicit PointCoordinates(const Qhull &q);
PointCoordinates(const Qhull &q, const std::string &aComment);
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment);
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
//! Use append() and appendPoints() for Coordinates and vector<coordT>
explicit PointCoordinates(QhullQh *qqh);
PointCoordinates(QhullQh *qqh, const std::string &aComment);
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment);
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
//! Use append() and appendPoints() for Coordinates and vector<coordT>
PointCoordinates(const PointCoordinates &other);
PointCoordinates & operator=(const PointCoordinates &other);
~PointCoordinates();
#//!\name Convert
//! QhullPoints coordinates, constData, data, count, size
#ifndef QHULL_NO_STL
void append(const std::vector<coordT> &otherCoordinates) { if(!otherCoordinates.empty()){ append((int)otherCoordinates.size(), &otherCoordinates[0]); } }
std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); }
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
void append(const QList<coordT> &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
QList<coordT> toQList() const { return point_coordinates.toQList(); }
#endif //QHULL_USES_QT
#//!\name GetSet
//! See QhullPoints for coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
void checkValid() const;
std::string comment() const { return describe_points; }
void makeValid() { defineAs(point_coordinates.count(), point_coordinates.data()); }
const Coordinates & getCoordinates() const { return point_coordinates; }
void setComment(const std::string &s) { describe_points= s; }
void setDimension(int i);
private:
//! disable QhullPoints.defineAs()
void defineAs(countT coordinatesCount, coordT *c) { QhullPoints::defineAs(coordinatesCount, c); }
public:
#//!\name ElementAccess
//! See QhullPoints for at, back, first, front, last, mid, [], value
#//!\name Foreach
//! See QhullPoints for begin, constBegin, end
Coordinates::ConstIterator beginCoordinates() const { return point_coordinates.begin(); }
Coordinates::Iterator beginCoordinates() { return point_coordinates.begin(); }
Coordinates::ConstIterator beginCoordinates(countT pointIndex) const;
Coordinates::Iterator beginCoordinates(countT pointIndex);
Coordinates::ConstIterator endCoordinates() const { return point_coordinates.end(); }
Coordinates::Iterator endCoordinates() { return point_coordinates.end(); }
#//!\name Search
//! See QhullPoints for contains, count, indexOf, lastIndexOf
#//!\name GetSet
PointCoordinates operator+(const PointCoordinates &other) const;
#//!\name Modify
//FIXUP QH11001: Add clear() and other modify operators from Coordinates.h. Include QhullPoint::operator=()
void append(countT coordinatesCount, const coordT *c); //! Dimension previously defined
void append(const coordT &c) { append(1, &c); } //! Dimension previously defined
void append(const QhullPoint &p);
//! See convert for std::vector and QList
void append(const Coordinates &c) { append(c.count(), c.data()); }
void append(const PointCoordinates &other);
void appendComment(const std::string &s);
void appendPoints(std::istream &in);
PointCoordinates & operator+=(const PointCoordinates &other) { append(other); return *this; }
PointCoordinates & operator+=(const coordT &c) { append(c); return *this; }
PointCoordinates & operator+=(const QhullPoint &p) { append(p); return *this; }
PointCoordinates & operator<<(const PointCoordinates &other) { return *this += other; }
PointCoordinates & operator<<(const coordT &c) { return *this += c; }
PointCoordinates & operator<<(const QhullPoint &p) { return *this += p; }
// reserve() is non-const
void reserveCoordinates(countT newCoordinates);
#//!\name Helpers
private:
int indexOffset(int i) const;
};//PointCoordinates
// No references to QhullPoint. Prevents use of QHULL_DECLARE_SEQUENTIAL_ITERATOR(PointCoordinates, QhullPoint)
class PointCoordinatesIterator
{
typedef PointCoordinates::const_iterator const_iterator;
private:
const PointCoordinates *c;
const_iterator i;
public:
PointCoordinatesIterator(const PointCoordinates &container) : c(&container), i(c->constBegin()) {}
PointCoordinatesIterator &operator=(const PointCoordinates &container) { c = &container; i = c->constBegin(); return *this; }
void toFront() { i = c->constBegin(); }
void toBack() { i = c->constEnd(); }
bool hasNext() const { return i != c->constEnd(); }
const QhullPoint next() { return *i++; }
const QhullPoint peekNext() const { return *i; }
bool hasPrevious() const { return i != c->constBegin(); }
const QhullPoint previous() { return *--i; }
const QhullPoint peekPrevious() const { const_iterator p = i; return *--p; }
bool findNext(const QhullPoint &t) { while(i != c->constEnd()){ if (*i++ == t) return true;} return false; }
bool findPrevious(const QhullPoint &t) { while(i != c->constBegin()){ if (*(--i) == t) return true;} return false; }
};//CoordinatesIterator
// FIXUP QH11002: Add MutablePointCoordinatesIterator after adding modify operators
\
}//namespace orgQhull
#//!\name Global
std::ostream & operator<<(std::ostream &os, const orgQhull::PointCoordinates &p);
#endif // QHPOINTCOORDINATES_H

View File

@@ -0,0 +1,358 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.cpp#4 $$Change: 2078 $
** $DateTime: 2016/02/07 16:53:56 $$Author: bbarber $
**
****************************************************************************/
#//! Qhull -- invoke qhull from C++
#//! Compile libqhull_r and Qhull together due to use of setjmp/longjmp()
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/RboxPoints.h"
#include "libqhullcpp/QhullQh.h"
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullFacetList.h"
#include <iostream>
using std::cerr;
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 {
#//!\name Global variables
const char s_unsupported_options[]=" Fd TI ";
const char s_not_output_options[]= " Fd TI A C d E H P Qb QbB Qbb Qc Qf Qg Qi Qm QJ Qr QR Qs Qt Qv Qx Qz Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 R Tc TC TM TP TR Tv TV TW U v V W ";
#//!\name Constructor, destructor, etc.
Qhull::
Qhull()
: qh_qh(0)
, origin_point()
, run_called(false)
, feasible_point()
{
allocateQhullQh();
}//Qhull
//! Invokes Qhull on rboxPoints
//! Same as runQhull()
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
Qhull::
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
: qh_qh(0)
, origin_point()
, run_called(false)
, feasible_point()
{
allocateQhullQh();
runQhull(rboxPoints, qhullCommand2);
}//Qhull rbox
//! Invokes Qhull on a set of input points
//! Same as runQhull()
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
Qhull::
Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
: qh_qh(0)
, origin_point()
, run_called(false)
, feasible_point()
{
allocateQhullQh();
runQhull(inputComment2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
}//Qhull points
void Qhull::
allocateQhullQh()
{
QHULL_LIB_CHECK /* Check for compatible library */
qh_qh= new QhullQh;
void *p= qh_qh;
void *p2= static_cast<qhT *>(qh_qh);
char *s= static_cast<char *>(p);
char *s2= static_cast<char *>(p2);
if(s!=s2){
throw QhullError(10074, "Qhull error: QhullQh at a different address than base type QhT (%d bytes). Please report compiler to qhull.org", int(s2-s));
}
}//allocateQhullQh
Qhull::
~Qhull() throw()
{
// Except for cerr, does not throw errors
if(qh_qh->hasQhullMessage()){
cerr<< "\nQhull output at end\n"; //FIXUP QH11005: where should error and log messages go on ~Qhull?
cerr<< qh_qh->qhullMessage();
qh_qh->clearQhullMessage();
}
delete qh_qh;
qh_qh= 0;
}//~Qhull
#//!\name GetSet
void Qhull::
checkIfQhullInitialized()
{
if(!initialized()){ // qh_initqhull_buffers() not called
throw QhullError(10023, "Qhull error: checkIfQhullInitialized failed. Call runQhull() first.");
}
}//checkIfQhullInitialized
//! Return feasiblePoint for halfspace intersection
//! If called before runQhull(), then it returns the value from setFeasiblePoint. qh.feasible_string overrides this value if it is defined.
Coordinates Qhull::
feasiblePoint() const
{
Coordinates result;
if(qh_qh->feasible_point){
result.append(qh_qh->hull_dim, qh_qh->feasible_point);
}else{
result= feasible_point;
}
return result;
}//feasiblePoint
//! Return origin point for qh.input_dim
QhullPoint Qhull::
inputOrigin()
{
QhullPoint result= origin();
result.setDimension(qh_qh->input_dim);
return result;
}//inputOrigin
#//!\name GetValue
double Qhull::
area(){
checkIfQhullInitialized();
if(!qh_qh->hasAreaVolume){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_getarea(qh_qh, qh_qh->facet_list);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return qh_qh->totarea;
}//area
double Qhull::
volume(){
checkIfQhullInitialized();
if(!qh_qh->hasAreaVolume){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_getarea(qh_qh, qh_qh->facet_list);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return qh_qh->totvol;
}//volume
#//!\name Foreach
//! Define QhullVertex::neighborFacets().
//! Automatically called if merging facets or computing the Voronoi diagram.
//! Noop if called multiple times.
void Qhull::
defineVertexNeighborFacets(){
checkIfQhullInitialized();
if(!qh_qh->hasAreaVolume){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_vertexneighbors(qh_qh);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
}//defineVertexNeighborFacets
QhullFacetList Qhull::
facetList() const{
return QhullFacetList(beginFacet(), endFacet());
}//facetList
QhullPoints Qhull::
points() const
{
return QhullPoints(qh_qh, qh_qh->hull_dim, qh_qh->num_points*qh_qh->hull_dim, qh_qh->first_point);
}//points
QhullPointSet Qhull::
otherPoints() const
{
return QhullPointSet(qh_qh, qh_qh->other_points);
}//otherPoints
//! Return vertices of the convex hull.
QhullVertexList Qhull::
vertexList() const{
return QhullVertexList(beginVertex(), endVertex());
}//vertexList
#//!\name Methods
void Qhull::
outputQhull()
{
checkIfQhullInitialized();
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_produce_output2(qh_qh);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}//outputQhull
void Qhull::
outputQhull(const char *outputflags)
{
checkIfQhullInitialized();
string cmd(" "); // qh_checkflags skips first word
cmd += outputflags;
char *command= const_cast<char*>(cmd.c_str());
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_clear_outputflags(qh_qh);
char *s = qh_qh->qhull_command + strlen(qh_qh->qhull_command) + 1; //space
strncat(qh_qh->qhull_command, command, sizeof(qh_qh->qhull_command)-strlen(qh_qh->qhull_command)-1);
qh_checkflags(qh_qh, command, const_cast<char *>(s_not_output_options));
qh_initflags(qh_qh, s);
qh_initqhull_outputflags(qh_qh);
if(qh_qh->KEEPminArea < REALmax/2
|| (0 != qh_qh->KEEParea + qh_qh->KEEPmerge + qh_qh->GOODvertex
+ qh_qh->GOODthreshold + qh_qh->GOODpoint + qh_qh->SPLITthresholds)){
facetT *facet;
qh_qh->ONLYgood= False;
FORALLfacet_(qh_qh->facet_list) {
facet->good= True;
}
qh_prepare_output(qh_qh);
}
qh_produce_output2(qh_qh);
if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
qh_check_points(qh_qh);
}
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}//outputQhull
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
void Qhull::
runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
{
runQhull(rboxPoints.comment().c_str(), rboxPoints.dimension(), rboxPoints.count(), &*rboxPoints.coordinates(), qhullCommand2);
}//runQhull, RboxPoints
//! pointCoordinates is a array of points, input sites ('d' or 'v'), or halfspaces with offset last ('H')
//! Derived from qh_new_qhull [user.c]
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
void Qhull::
runQhull(const char *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand)
{
/* gcc may issue a "might be clobbered" warning for pointDimension and pointCoordinates [-Wclobbered].
These parameters are not referenced after a longjmp() and hence not clobbered.
See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
if(run_called){
throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed.");
}
run_called= true;
string s("qhull ");
s += qhullCommand;
char *command= const_cast<char*>(s.c_str());
/************* Expansion of QH_TRY_ for debugging
int QH_TRY_status;
if(qh_qh->NOerrexit){
qh_qh->NOerrexit= False;
QH_TRY_status= setjmp(qh_qh->errexit);
}else{
QH_TRY_status= QH_TRY_ERROR;
}
if(!QH_TRY_status){
*************/
QH_TRY_(qh_qh){ // no object creation -- destructors are skipped on longjmp()
qh_checkflags(qh_qh, command, const_cast<char *>(s_unsupported_options));
qh_initflags(qh_qh, command);
*qh_qh->rbox_command= '\0';
strncat( qh_qh->rbox_command, inputComment, sizeof(qh_qh->rbox_command)-1);
if(qh_qh->DELAUNAY){
qh_qh->PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput()
}
pointT *newPoints= const_cast<pointT*>(pointCoordinates);
int newDimension= pointDimension;
int newIsMalloc= False;
if(qh_qh->HALFspace){
--newDimension;
initializeFeasiblePoint(newDimension);
newPoints= qh_sethalfspace_all(qh_qh, pointDimension, pointCount, newPoints, qh_qh->feasible_point);
newIsMalloc= True;
}
qh_init_B(qh_qh, newPoints, pointCount, newDimension, newIsMalloc);
qh_qhull(qh_qh);
qh_check_output(qh_qh);
qh_prepare_output(qh_qh);
if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
qh_check_points(qh_qh);
}
}
qh_qh->NOerrexit= true;
for(int k= qh_qh->hull_dim; k--; ){ // Do not move into QH_TRY block. It may throw an error
origin_point << 0.0;
}
// BBS: throw up the error to prevent crash
try {
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
catch (QhullError& e) {
throw e;
}
}//runQhull
#//!\name Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
//! initialize qh.feasible_point for half-space intersection
//! Sets from qh.feasible_string if available, otherwise from Qhull::feasible_point
//! called only once from runQhull(), otherwise it leaks memory (the same as qh_setFeasible)
void Qhull::
initializeFeasiblePoint(int hulldim)
{
if(qh_qh->feasible_string){
qh_setfeasible(qh_qh, hulldim);
}else{
if(feasible_point.isEmpty()){
qh_fprintf(qh_qh, qh_qh->ferr, 6209, "qhull error: missing feasible point for halfspace intersection. Use option 'Hn,n' or Qhull::setFeasiblePoint before runQhull()\n");
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
}
if(feasible_point.size()!=(size_t)hulldim){
qh_fprintf(qh_qh, qh_qh->ferr, 6210, "qhull error: dimension of feasiblePoint should be %d. It is %u", hulldim, feasible_point.size());
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
}
if (!(qh_qh->feasible_point= (coordT*)qh_malloc(hulldim * sizeof(coordT)))) {
qh_fprintf(qh_qh, qh_qh->ferr, 6202, "qhull error: insufficient memory for feasible point\n");
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
}
coordT *t= qh_qh->feasible_point;
// No qh_... routines after here -- longjmp() ignores destructor
for(Coordinates::ConstIterator p=feasible_point.begin(); p<feasible_point.end(); p++){
*t++= *p;
}
}
}//initializeFeasiblePoint
}//namespace orgQhull

View File

@@ -0,0 +1,132 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.h#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLCPP_H
#define QHULLCPP_H
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/QhullFacet.h"
namespace orgQhull {
/***
Compile qhullcpp and libqhull with the same compiler. setjmp() and longjmp() must be the same.
#define QHULL_NO_STL
Do not supply conversions to STL
Coordinates.h requires <vector>. It could be rewritten for another vector class such as QList
#define QHULL_USES_QT
Supply conversions to QT
qhulltest requires QT. It is defined in RoadTest.h
#define QHULL_ASSERT
Defined by QhullError.h
It invokes assert()
*/
#//!\name Used here
class QhullFacetList;
class QhullPoints;
class QhullQh;
class RboxPoints;
#//!\name Defined here
class Qhull;
//! Interface to Qhull from C++
class Qhull {
private:
#//!\name Members and friends
QhullQh * qh_qh; //! qhT for this instance
Coordinates origin_point; //! origin for qh_qh->hull_dim. Set by runQhull()
bool run_called; //! True at start of runQhull. Errors if call again.
Coordinates feasible_point; //! feasible point for half-space intersection (alternative to qh.feasible_string for qh.feasible_point)
public:
#//!\name Constructors
Qhull(); //!< call runQhull() next
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
~Qhull() throw();
private: //! Disable copy constructor and assignment. Qhull owns QhullQh.
Qhull(const Qhull &);
Qhull & operator=(const Qhull &);
private:
void allocateQhullQh();
public:
#//!\name GetSet
void checkIfQhullInitialized();
int dimension() const { return qh_qh->input_dim; } //!< Dimension of input and result
void disableOutputStream() { qh_qh->disableOutputStream(); }
void enableOutputStream() { qh_qh->enableOutputStream(); }
countT facetCount() const { return qh_qh->num_facets; }
Coordinates feasiblePoint() const;
int hullDimension() const { return qh_qh->hull_dim; } //!< Dimension of the computed hull
bool hasOutputStream() const { return qh_qh->hasOutputStream(); }
bool initialized() const { return (qh_qh->hull_dim>0); }
const char * inputComment() const { return qh_qh->rbox_command; }
QhullPoint inputOrigin();
//! non-const due to QhullPoint
QhullPoint origin() { QHULL_ASSERT(initialized()); return QhullPoint(qh_qh, origin_point.data()); }
QhullQh * qh() const { return qh_qh; };
const char * qhullCommand() const { return qh_qh->qhull_command; }
const char * rboxCommand() const { return qh_qh->rbox_command; }
int rotateRandom() const { return qh_qh->ROTATErandom; } //!< Return QRn for repeating QR0 runs
void setFeasiblePoint(const Coordinates &c) { feasible_point= c; } //!< Sets qh.feasible_point via initializeFeasiblePoint
countT vertexCount() const { return qh_qh->num_vertices; }
#//!\name Delegated to QhullQh
double angleEpsilon() const { return qh_qh->angleEpsilon(); } //!< Epsilon for hyperplane angle equality
void appendQhullMessage(const std::string &s) { qh_qh->appendQhullMessage(s); }
void clearQhullMessage() { qh_qh->clearQhullMessage(); }
double distanceEpsilon() const { return qh_qh->distanceEpsilon(); } //!< Epsilon for distance to hyperplane
double factorEpsilon() const { return qh_qh->factorEpsilon(); } //!< Factor for angleEpsilon and distanceEpsilon
std::string qhullMessage() const { return qh_qh->qhullMessage(); }
bool hasQhullMessage() const { return qh_qh->hasQhullMessage(); }
int qhullStatus() const { return qh_qh->qhullStatus(); }
void setErrorStream(std::ostream *os) { qh_qh->setErrorStream(os); }
void setFactorEpsilon(double a) { qh_qh->setFactorEpsilon(a); }
void setOutputStream(std::ostream *os) { qh_qh->setOutputStream(os); }
#//!\name ForEach
QhullFacet beginFacet() const { return QhullFacet(qh_qh, qh_qh->facet_list); }
QhullVertex beginVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_list); }
void defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram
QhullFacet endFacet() const { return QhullFacet(qh_qh, qh_qh->facet_tail); }
QhullVertex endVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_tail); }
QhullFacetList facetList() const;
QhullFacet firstFacet() const { return beginFacet(); }
QhullVertex firstVertex() const { return beginVertex(); }
QhullPoints points() const;
QhullPointSet otherPoints() const;
//! Same as points().coordinates()
coordT * pointCoordinateBegin() const { return qh_qh->first_point; }
coordT * pointCoordinateEnd() const { return qh_qh->first_point + qh_qh->num_points*qh_qh->hull_dim; }
QhullVertexList vertexList() const;
#//!\name Methods
double area();
void outputQhull();
void outputQhull(const char * outputflags);
void runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
void runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
double volume();
#//!\name Helpers
private:
void initializeFeasiblePoint(int hulldim);
};//Qhull
}//namespace orgQhull
#endif // QHULLCPP_H

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullError.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLERROR_H
#define QHULLERROR_H
#include "libqhullcpp/RoadError.h"
// No dependencies on libqhull
#ifndef QHULL_ASSERT
#define QHULL_ASSERT assert
#include <assert.h>
#endif
namespace orgQhull {
#//!\name Defined here
//! QhullError -- std::exception class for Qhull
class QhullError;
class QhullError : public RoadError {
public:
#//!\name Constants
enum {
QHULLfirstError= 10000, //MSG_QHULL_ERROR in Qhull's user.h
QHULLlastError= 10078,
NOthrow= 1 //! For flag to indexOf()
};
#//!\name Constructors
// default constructors
QhullError() : RoadError() {};
QhullError(const QhullError &other) : RoadError(other) {}
QhullError(int code, const std::string &message) : RoadError(code, message) {};
QhullError(int code, const char *fmt) : RoadError(code, fmt) {};
QhullError(int code, const char *fmt, int d) : RoadError(code, fmt, d) {};
QhullError(int code, const char *fmt, int d, int d2) : RoadError(code, fmt, d, d2) {};
QhullError(int code, const char *fmt, int d, int d2, float f) : RoadError(code, fmt, d, d2, f) {};
QhullError(int code, const char *fmt, int d, int d2, float f, const char *s) : RoadError(code, fmt, d, d2, f, s) {};
QhullError(int code, const char *fmt, int d, int d2, float f, const void *x) : RoadError(code, fmt, d, d2, f, x) {};
QhullError(int code, const char *fmt, int d, int d2, float f, int i) : RoadError(code, fmt, d, d2, f, i) {};
QhullError(int code, const char *fmt, int d, int d2, float f, long long i) : RoadError(code, fmt, d, d2, f, i) {};
QhullError(int code, const char *fmt, int d, int d2, float f, double e) : RoadError(code, fmt, d, d2, f, e) {};
QhullError &operator=(const QhullError &other) { this->RoadError::operator=(other); return *this; }
~QhullError() throw() {}
};//class QhullError
}//namespace orgQhull
#//!\name Global
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os << e.what(); }
#endif // QHULLERROR_H

View File

@@ -0,0 +1,519 @@
/****************************************************************************
**
** 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

View File

@@ -0,0 +1,151 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACET_H
#define QHULLFACET_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullHyperplane.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullPointSet.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Coordinates;
class Qhull;
class QhullFacetSet;
class QhullRidge;
class QhullVertex;
class QhullVertexSet;
#//!\name Defined here
class QhullFacet;
typedef QhullSet<QhullRidge> QhullRidgeSet;
//! A QhullFacet is the C++ equivalent to Qhull's facetT*
class QhullFacet {
#//!\name Defined here
public:
typedef facetT * base_type; // for QhullVertexSet
private:
#//!\name Fields -- no additions (QhullFacetSet of facetT*)
facetT * qh_facet; //!< Corresponding facetT, may be 0 for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
QhullQh * qh_qh; //!< QhullQh/qhT for facetT, may be 0
#//!\name Class objects
static facetT s_empty_facet; // needed for shallow copy
public:
#//!\name Constructors
QhullFacet() : qh_facet(&s_empty_facet), qh_qh(0) {}
explicit QhullFacet(const Qhull &q);
QhullFacet(const Qhull &q, facetT *f);
explicit QhullFacet(QhullQh *qqh) : qh_facet(&s_empty_facet), qh_qh(qqh) {}
QhullFacet(QhullQh *qqh, facetT *f) : qh_facet(f ? f : &s_empty_facet), qh_qh(qqh) {}
// Creates an alias. Does not copy QhullFacet. Needed for return by value and parameter passing
QhullFacet(const QhullFacet &other) : qh_facet(other.qh_facet ? other.qh_facet : &s_empty_facet), qh_qh(other.qh_qh) {}
// Creates an alias. Does not copy QhullFacet. Needed for vector<QhullFacet>
QhullFacet & operator=(const QhullFacet &other) { qh_facet= other.qh_facet ? other.qh_facet : &s_empty_facet; qh_qh= other.qh_qh; return *this; }
~QhullFacet() {}
#//!\name GetSet
int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
QhullPoint getCenter() { return getCenter(qh_PRINTpoints); }
QhullPoint getCenter(qh_PRINT printFormat);
facetT * getBaseT() const { return getFacetT(); } //!< For QhullSet<QhullFacet>
// Do not define facetT(). It conflicts with return type facetT*
facetT * getFacetT() const { return qh_facet; }
QhullHyperplane hyperplane() const { return QhullHyperplane(qh_qh, dimension(), qh_facet->normal, qh_facet->offset); }
countT id() const { return (qh_facet ? qh_facet->id : (int)qh_IDunknown); }
QhullHyperplane innerplane() const;
bool isValid() const { return qh_qh && qh_facet && qh_facet != &s_empty_facet; }
bool isGood() const { return qh_facet && qh_facet->good; }
bool isSimplicial() const { return qh_facet && qh_facet->simplicial; }
bool isTopOrient() const { return qh_facet && qh_facet->toporient; }
bool isTriCoplanar() const { return qh_facet && qh_facet->tricoplanar; }
bool isUpperDelaunay() const { return qh_facet && qh_facet->upperdelaunay; }
QhullFacet next() const { return QhullFacet(qh_qh, qh_facet->next); }
bool operator==(const QhullFacet &other) const { return qh_facet==other.qh_facet; }
bool operator!=(const QhullFacet &other) const { return !operator==(other); }
QhullHyperplane outerplane() const;
QhullFacet previous() const { return QhullFacet(qh_qh, qh_facet->previous); }
QhullQh * qh() const { return qh_qh; }
QhullFacet tricoplanarOwner() const;
QhullPoint voronoiVertex();
#//!\name value
//! Undefined if c.size() != dimension()
double distance(const Coordinates &c) const { return distance(c.data()); }
double distance(const pointT *p) const { return distance(QhullPoint(qh_qh, const_cast<coordT *>(p))); }
double distance(const QhullPoint &p) const { return hyperplane().distance(p); }
double facetArea();
#//!\name foreach
// Can not inline. Otherwise circular reference
QhullPointSet coplanarPoints() const;
QhullFacetSet neighborFacets() const;
QhullPointSet outsidePoints() const;
QhullRidgeSet ridges() const;
QhullVertexSet vertices() const;
#//!\name IO
struct PrintCenter{
QhullFacet * facet; // non-const due to facet.center()
const char * message;
qh_PRINT print_format;
PrintCenter(QhullFacet &f, qh_PRINT printFormat, const char * s) : facet(&f), message(s), print_format(printFormat){}
};//PrintCenter
PrintCenter printCenter(qh_PRINT printFormat, const char *message) { return PrintCenter(*this, printFormat, message); }
struct PrintFacet{
QhullFacet * facet; // non-const due to f->center()
const char * message;
explicit PrintFacet(QhullFacet &f, const char * s) : facet(&f), message(s) {}
};//PrintFacet
PrintFacet print(const char *message) { return PrintFacet(*this, message); }
struct PrintFlags{
const QhullFacet *facet;
const char * message;
PrintFlags(const QhullFacet &f, const char *s) : facet(&f), message(s) {}
};//PrintFlags
PrintFlags printFlags(const char *message) const { return PrintFlags(*this, message); }
struct PrintHeader{
QhullFacet * facet; // non-const due to f->center()
PrintHeader(QhullFacet &f) : facet(&f) {}
};//PrintHeader
PrintHeader printHeader() { return PrintHeader(*this); }
struct PrintRidges{
const QhullFacet *facet;
PrintRidges(QhullFacet &f) : facet(&f) {}
};//PrintRidges
PrintRidges printRidges() { return PrintRidges(*this); }
};//class QhullFacet
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFacet &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintCenter &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFlags &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintHeader &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintRidges &pr);
std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
#endif // QHULLFACET_H

View File

@@ -0,0 +1,174 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacetList -- Qhull's linked facets, as a C++ class
#include "libqhullcpp/QhullFacetList.h"
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullVertex.h"
using std::string;
using std::vector;
#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 Constructors
QhullFacetList::
QhullFacetList(const Qhull &q, facetT *b, facetT *e )
: QhullLinkedList<QhullFacet>(QhullFacet(q, b), QhullFacet(q, e))
, select_all(false)
{
}
#//!\name Conversions
// See qt_qhull.cpp for QList conversions
#ifndef QHULL_NO_STL
std::vector<QhullFacet> QhullFacetList::
toStdVector() const
{
QhullLinkedListIterator<QhullFacet> i(*this);
std::vector<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.push_back(f);
}
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#ifndef QHULL_NO_STL
//! Same as PrintVertices
std::vector<QhullVertex> QhullFacetList::
vertices_toStdVector() const
{
std::vector<QhullVertex> vs;
QhullVertexSet qvs(qh(), first().getFacetT(), 0, isSelectAll());
for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
vs.push_back(*i);
}
return vs;
}//vertices_toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
bool QhullFacetList::
contains(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullLinkedList<QhullFacet>::contains(facet);
}
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
return true;
}
}
return false;
}//contains
int QhullFacetList::
count() const
{
if(isSelectAll()){
return QhullLinkedList<QhullFacet>::count();
}
int counter= 0;
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
if((*i).isGood()){
counter++;
}
}
return counter;
}//count
int QhullFacetList::
count(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullLinkedList<QhullFacet>::count(facet);
}
int counter= 0;
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
counter++;
}
}
return counter;
}//count
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetList;
using orgQhull::QhullVertex;
using orgQhull::QhullVertexSet;
ostream &
operator<<(ostream &os, const QhullFacetList::PrintFacetList &pr)
{
os << pr.print_message;
QhullFacetList fs= *pr.facet_list;
os << "Vertices for " << fs.count() << " facets" << endl;
os << fs.printVertices();
os << fs.printFacets();
return os;
}//operator<<
//! Print facet list to stream. From qh_printafacet [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacetList::PrintFacets &pr)
{
for(QhullFacetList::const_iterator i= pr.facet_list->begin(); i != pr.facet_list->end(); ++i){
QhullFacet f= *i;
if(pr.facet_list->isSelectAll() || f.isGood()){
os << f.print("");
}
}
return os;
}//printFacets
//! Print vertices of good faces in facet list to stream. From qh_printvertexlist [io_r.c]
//! Same as vertices_toStdVector
ostream &
operator<<(ostream &os, const QhullFacetList::PrintVertices &pr)
{
QhullVertexSet vs(pr.facet_list->qh(), pr.facet_list->first().getFacetT(), NULL, pr.facet_list->isSelectAll());
for(QhullVertexSet::iterator i=vs.begin(); i!=vs.end(); ++i){
QhullVertex v= *i;
os << v.print("");
}
return os;
}//printVertices
std::ostream &
operator<<(ostream &os, const QhullFacetList &fs)
{
os << fs.printFacets();
return os;
}//QhullFacetList

View File

@@ -0,0 +1,106 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACETLIST_H
#define QHULLFACETLIST_H
#include "libqhullcpp/QhullLinkedList.h"
#include "libqhullcpp/QhullFacet.h"
#include <ostream>
#ifndef QHULL_NO_STL
#include <vector>
#endif
namespace orgQhull {
#//!\name Used here
class Qhull;
class QhullFacet;
class QhullQh;
#//!\name Defined here
//! QhullFacetList -- List of QhullFacet/facetT, as a C++ class.
//!\see QhullFacetSet.h
class QhullFacetList;
//! QhullFacetListIterator -- if(f.isGood()){ ... }
typedef QhullLinkedListIterator<QhullFacet> QhullFacetListIterator;
class QhullFacetList : public QhullLinkedList<QhullFacet> {
#//!\name Fields
private:
bool select_all; //! True if include bad facets. Default is false.
#//!\name Constructors
public:
QhullFacetList(const Qhull &q, facetT *b, facetT *e);
QhullFacetList(QhullQh *qqh, facetT *b, facetT *e);
QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList<QhullFacet>(b, e), select_all(false) {}
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
QhullFacetList(const QhullFacetList &other) : QhullLinkedList<QhullFacet>(*other.begin(), *other.end()), select_all(other.select_all) {}
QhullFacetList & operator=(const QhullFacetList &other) { QhullLinkedList<QhullFacet>::operator =(other); select_all= other.select_all; return *this; }
~QhullFacetList() {}
private: //!Disable default constructor. See QhullLinkedList
QhullFacetList();
public:
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<QhullFacet> toStdVector() const;
std::vector<QhullVertex> vertices_toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullFacet> toQList() const;
QList<QhullVertex> vertices_toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
//! Filtered by facet.isGood(). May be 0 when !isEmpty().
countT count() const;
bool contains(const QhullFacet &f) const;
countT count(const QhullFacet &f) const;
bool isSelectAll() const { return select_all; }
QhullQh * qh() const { return first().qh(); }
void selectAll() { select_all= true; }
void selectGood() { select_all= false; }
//!< operator==() does not depend on isGood()
#//!\name IO
struct PrintFacetList{
const QhullFacetList *facet_list;
const char * print_message; //!< non-null message
PrintFacetList(const QhullFacetList &fl, const char *message) : facet_list(&fl), print_message(message) {}
};//PrintFacetList
PrintFacetList print(const char *message) const { return PrintFacetList(*this, message); }
struct PrintFacets{
const QhullFacetList *facet_list;
PrintFacets(const QhullFacetList &fl) : facet_list(&fl) {}
};//PrintFacets
PrintFacets printFacets() const { return PrintFacets(*this); }
struct PrintVertices{
const QhullFacetList *facet_list;
PrintVertices(const QhullFacetList &fl) : facet_list(&fl) {}
};//PrintVertices
PrintVertices printVertices() const { return PrintVertices(*this); }
};//class QhullFacetList
}//namespace orgQhull
#//!\name == Global namespace =========================================
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacetList &p);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacets &p);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintVertices &p);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList &fs);
#endif // QHULLFACETLIST_H

View File

@@ -0,0 +1,147 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetSet.cpp#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacetSet -- Qhull's linked facets, as a C++ class
#include "libqhullcpp/QhullFacetSet.h"
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullVertex.h"
#ifndef QHULL_NO_STL
using std::vector;
#endif
#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 Conversions
// See qt-qhull.cpp for QList conversions
#ifndef QHULL_NO_STL
std::vector<QhullFacet> QhullFacetSet::
toStdVector() const
{
QhullSetIterator<QhullFacet> i(*this);
std::vector<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.push_back(f);
}
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
bool QhullFacetSet::
contains(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullSet<QhullFacet>::contains(facet);
}
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
return true;
}
}
return false;
}//contains
int QhullFacetSet::
count() const
{
if(isSelectAll()){
return QhullSet<QhullFacet>::count();
}
int counter= 0;
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f.isGood()){
counter++;
}
}
return counter;
}//count
int QhullFacetSet::
count(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullSet<QhullFacet>::count(facet);
}
int counter= 0;
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
counter++;
}
}
return counter;
}//count
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetSet;
ostream &
operator<<(ostream &os, const QhullFacetSet &fs)
{
os << fs.print("");
return os;
}//<<QhullFacetSet
ostream &
operator<<(ostream &os, const QhullFacetSet::PrintFacetSet &pr)
{
os << pr.print_message;
QhullFacetSet fs= *pr.facet_set;
for(QhullFacetSet::iterator i=fs.begin(); i != fs.end(); ++i){
QhullFacet f= *i;
if(fs.isSelectAll() || f.isGood()){
os << f;
}
}
return os;
}//<< QhullFacetSet::PrintFacetSet
//! Print facet identifiers to stream. Space prefix. From qh_printfacetheader [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacetSet::PrintIdentifiers &p)
{
os << p.print_message;
for(QhullFacetSet::const_iterator i=p.facet_set->begin(); i!=p.facet_set->end(); ++i){
const QhullFacet f= *i;
if(f.getFacetT()==qh_MERGEridge){
os << " MERGE";
}else if(f.getFacetT()==qh_DUPLICATEridge){
os << " DUP";
}else if(p.facet_set->isSelectAll() || f.isGood()){
os << " f" << f.id();
}
}
os << endl;
return os;
}//<<QhullFacetSet::PrintIdentifiers

View File

@@ -0,0 +1,97 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetSet.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACETSET_H
#define QHULLFACETSET_H
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullFacet.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Qhull;
#//!\name Defined here
//! QhullFacetSet -- a set of Qhull facets, as a C++ class. See QhullFacetList.h
class QhullFacetSet;
typedef QhullSetIterator<QhullFacet> QhullFacetSetIterator;
class QhullFacetSet : public QhullSet<QhullFacet> {
#//!\name Defined here
public:
typedef facetT * base_type; // for QhullVertexSet
private:
#//!\name Fields
bool select_all; //! True if include bad facets. Default is false.
public:
#//!\name Constructor
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
QhullFacetSet(const Qhull &q, setT *s) : QhullSet<QhullFacet>(q, s), select_all(false) {}
QhullFacetSet(QhullQh *qqh, setT *s) : QhullSet<QhullFacet>(qqh, s), select_all(false) {}
//!Copy constructor copies pointers but not contents. Needed for return by value and parameter passing.
QhullFacetSet(const QhullFacetSet &other) : QhullSet<QhullFacet>(other), select_all(other.select_all) {}
//!Assignment copies pointers but not contents.
QhullFacetSet & operator=(const QhullFacetSet &other) { QhullSet<QhullFacet>::operator=(other); select_all= other.select_all; return *this; }
private:
//!Disable default constructor. See QhullSetBase
QhullFacetSet();
public:
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<QhullFacet> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullFacet> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
//! Filtered by facet.isGood(). May be 0 when !isEmpty().
countT count() const;
bool contains(const QhullFacet &f) const;
countT count(const QhullFacet &f) const;
bool isSelectAll() const { return select_all; }
//! operator==() does not depend on isGood()
void selectAll() { select_all= true; }
void selectGood() { select_all= false; }
#//!\name IO
// Not same as QhullFacetList#IO. A QhullFacetSet is a component of a QhullFacetList.
struct PrintFacetSet{
const QhullFacetSet *facet_set;
const char * print_message; //!< non-null message
PrintFacetSet(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
};//PrintFacetSet
const PrintFacetSet print(const char *message) const { return PrintFacetSet(message, this); }
struct PrintIdentifiers{
const QhullFacetSet *facet_set;
const char * print_message; //!< non-null message
PrintIdentifiers(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
};//PrintIdentifiers
PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
};//class QhullFacetSet
}//namespace orgQhull
#//!\name == Global namespace =========================================
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet &fs);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintFacetSet &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintIdentifiers &p);
#endif // QHULLFACETSET_H

View File

@@ -0,0 +1,187 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullHyperplane.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/QhullHyperplane.h"
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullPoint.h"
#include <iostream>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Constructors
QhullHyperplane::
QhullHyperplane(const Qhull &q)
: hyperplane_coordinates(0)
, qh_qh(q.qh())
, hyperplane_offset(0.0)
, hyperplane_dimension(0)
{
}
QhullHyperplane::
QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset)
: hyperplane_coordinates(c)
, qh_qh(q.qh())
, hyperplane_offset(hyperplaneOffset)
, hyperplane_dimension(hyperplaneDimension)
{
}
#//!\name Conversions
// See qt-qhull.cpp for QList conversions
#ifndef QHULL_NO_STL
std::vector<coordT> QhullHyperplane::
toStdVector() const
{
QhullHyperplaneIterator i(*this);
std::vector<coordT> fs;
while(i.hasNext()){
fs.push_back(i.next());
}
fs.push_back(hyperplane_offset);
return fs;
}//toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
//! Return true if equal
//! If qh_qh defined, tests qh.distanceEpsilon and qh.angleEpsilon
//! otherwise, tests equal coordinates and offset
bool QhullHyperplane::
operator==(const QhullHyperplane &other) const
{
if(hyperplane_dimension!=other.hyperplane_dimension || !hyperplane_coordinates || !other.hyperplane_coordinates){
return false;
}
double d= fabs(hyperplane_offset-other.hyperplane_offset);
if(d > (qh_qh ? qh_qh->distanceEpsilon() : 0.0)){
return false;
}
double angle= hyperplaneAngle(other);
double a= fabs(angle-1.0);
if(a > (qh_qh ? qh_qh->angleEpsilon() : 0.0)){
return false;
}
return true;
}//operator==
#//!\name Methods
//! Return distance from point to hyperplane.
//! If greater than zero, the point is above the facet (i.e., outside).
// qh_distplane [geom_r.c], QhullFacet::distance, and QhullHyperplane::distance are copies
// Does not support RANDOMdist or logging
double QhullHyperplane::
distance(const QhullPoint &p) const
{
const coordT *point= p.coordinates();
int dim= p.dimension();
QHULL_ASSERT(dim==dimension());
const coordT *normal= coordinates();
double dist;
switch (dim){
case 2:
dist= offset() + point[0] * normal[0] + point[1] * normal[1];
break;
case 3:
dist= offset() + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
break;
case 4:
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
break;
case 5:
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
break;
case 6:
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
break;
case 7:
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
break;
case 8:
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
break;
default:
dist= offset();
for (int k=dim; k--; )
dist += *point++ * *normal++;
break;
}
return dist;
}//distance
double QhullHyperplane::
hyperplaneAngle(const QhullHyperplane &other) const
{
volatile realT result= 0.0;
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
result= qh_getangle(qh_qh, hyperplane_coordinates, other.hyperplane_coordinates);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
return result;
}//hyperplaneAngle
double QhullHyperplane::
norm() const {
double d= 0.0;
const coordT *c= coordinates();
for (int k=dimension(); k--; ){
d += *c * *c;
++c;
}
return sqrt(d);
}//norm
}//namespace orgQhull
#//!\name Global functions
using std::ostream;
using orgQhull::QhullHyperplane;
#//!\name GetSet<<
ostream &
operator<<(ostream &os, const QhullHyperplane &p)
{
os << p.print("");
return os;
}
ostream &
operator<<(ostream &os, const QhullHyperplane::PrintHyperplane &pr)
{
os << pr.print_message;
QhullHyperplane p= *pr.hyperplane;
const realT *c= p.coordinates();
for(int k=p.dimension(); k--; ){
realT r= *c++;
if(pr.print_message){
os << " " << r; // FIXUP QH11010 %8.4g
}else{
os << " " << r; // FIXUP QH11010 qh_REAL_1
}
}
os << pr.hyperplane_offset_message << " " << p.offset();
os << std::endl;
return os;
}//PrintHyperplane

View File

@@ -0,0 +1,123 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullHyperplane.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHHYPERPLANE_H
#define QHHYPERPLANE_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullIterator.h"
#include "libqhullcpp/QhullQh.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Qhull;
class QhullPoint;
#//!\name Defined here
//! QhullHyperplane as an offset, dimension, and pointer to coordinates
class QhullHyperplane;
//! Java-style iterator for QhullHyperplane coordinates
class QhullHyperplaneIterator;
class QhullHyperplane { // Similar to QhullPoint
public:
#//!\name Subtypes
typedef const coordT * iterator;
typedef const coordT * const_iterator;
typedef QhullHyperplane::iterator Iterator;
typedef QhullHyperplane::const_iterator ConstIterator;
private:
#//!\name Fields
coordT * hyperplane_coordinates; //!< Normal to hyperplane. facetT.normal is normalized to 1.0
QhullQh * qh_qh; //!< qhT for distanceEpsilon() in operator==
coordT hyperplane_offset; //!< Distance from hyperplane to origin
int hyperplane_dimension; //!< Dimension of hyperplane
#//!\name Construct
public:
QhullHyperplane() : hyperplane_coordinates(0), qh_qh(0), hyperplane_offset(0.0), hyperplane_dimension(0) {}
explicit QhullHyperplane(const Qhull &q);
QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset);
explicit QhullHyperplane(QhullQh *qqh) : hyperplane_coordinates(0), qh_qh(qqh), hyperplane_offset(0.0), hyperplane_dimension(0) {}
QhullHyperplane(QhullQh *qqh, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) : hyperplane_coordinates(c), qh_qh(qqh), hyperplane_offset(hyperplaneOffset), hyperplane_dimension(hyperplaneDimension) {}
// Creates an alias. Does not copy the hyperplane's coordinates. Needed for return by value and parameter passing.
QhullHyperplane(const QhullHyperplane &other) : hyperplane_coordinates(other.hyperplane_coordinates), qh_qh(other.qh_qh), hyperplane_offset(other.hyperplane_offset), hyperplane_dimension(other.hyperplane_dimension) {}
// Creates an alias. Does not copy the hyperplane's coordinates. Needed for vector<QhullHyperplane>
QhullHyperplane & operator=(const QhullHyperplane &other) { hyperplane_coordinates= other.hyperplane_coordinates; qh_qh= other.qh_qh; hyperplane_offset= other.hyperplane_offset; hyperplane_dimension= other.hyperplane_dimension; return *this; }
~QhullHyperplane() {}
#//!\name Conversions --
//! Includes offset at end
#ifndef QHULL_NO_STL
std::vector<coordT> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
public:
const coordT * coordinates() const { return hyperplane_coordinates; }
coordT * coordinates() { return hyperplane_coordinates; }
void defineAs(int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) { QHULL_ASSERT(hyperplaneDimension>=0); hyperplane_coordinates= c; hyperplane_dimension= hyperplaneDimension; hyperplane_offset= hyperplaneOffset; }
//! Creates an alias to other using the same qh_qh
void defineAs(QhullHyperplane &other) { hyperplane_coordinates= other.coordinates(); hyperplane_dimension= other.dimension(); hyperplane_offset= other.offset(); }
int dimension() const { return hyperplane_dimension; }
bool isValid() const { return hyperplane_coordinates!=0 && hyperplane_dimension>0; }
coordT offset() const { return hyperplane_offset; }
bool operator==(const QhullHyperplane &other) const;
bool operator!=(const QhullHyperplane &other) const { return !operator==(other); }
const coordT & operator[](int idx) const { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
coordT & operator[](int idx) { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
void setCoordinates(coordT *c) { hyperplane_coordinates= c; }
void setDimension(int hyperplaneDimension) { hyperplane_dimension= hyperplaneDimension; }
void setOffset(coordT hyperplaneOffset) { hyperplane_offset= hyperplaneOffset; }
#//!\name iterator
iterator begin() { return hyperplane_coordinates; }
const_iterator begin() const { return hyperplane_coordinates; }
const_iterator constBegin() const { return hyperplane_coordinates; }
const_iterator constEnd() const { return hyperplane_coordinates+hyperplane_dimension; }
int count() { return hyperplane_dimension; }
iterator end() { return hyperplane_coordinates+hyperplane_dimension; }
const_iterator end() const { return hyperplane_coordinates+hyperplane_dimension; }
size_t size() { return (size_t)hyperplane_dimension; }
#//!\name Methods
double distance(const QhullPoint &p) const;
double hyperplaneAngle(const QhullHyperplane &other) const;
double norm() const;
#//!\name IO
struct PrintHyperplane{
const QhullHyperplane *hyperplane;
const char * print_message; //!< non-null message
const char * hyperplane_offset_message; //!< non-null message
PrintHyperplane(const char *message, const char *offsetMessage, const QhullHyperplane &p) : hyperplane(&p), print_message(message), hyperplane_offset_message(offsetMessage) {}
};//PrintHyperplane
PrintHyperplane print(const char *message) const { return PrintHyperplane(message, "", *this); }
PrintHyperplane print(const char *message, const char *offsetMessage) const { return PrintHyperplane(message, offsetMessage, *this); }
};//QhullHyperplane
QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullHyperplane, coordT)
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane::PrintHyperplane &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p);
#endif // QHHYPERPLANE_H

View File

@@ -0,0 +1,173 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullIterator.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLITERATOR_H
#define QHULLITERATOR_H
#include "libqhull_r/qhull_ra.h"
#include <assert.h>
#include <iterator>
#include <string>
#include <vector>
namespace orgQhull {
#//!\name Defined here
//! Only QHULL_DECLARE_SEQUENTIAL_ITERATOR is used in libqhullcpp. The others need further development
//! QHULL_DECLARE_SEQUENTIAL_ITERATOR(C) -- Declare a Java-style iterator
//! QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) -- Declare a mutable Java-style iterator
//! QHULL_DECLARE_SET_ITERATOR(C) -- Declare a set iterator
//! QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) -- Declare a mutable set iterator
//! Derived from Qt/core/tools/qiterator.h and qset_r.h/FOREACHsetelement_()
// Stores C* as done in Mutable... Assumes the container is not deleted.
// C::const_iterator is an STL-style iterator that returns T&
#define QHULL_DECLARE_SEQUENTIAL_ITERATOR(C, T) \
\
class C##Iterator \
{ \
typedef C::const_iterator const_iterator; \
const C *c; \
const_iterator i; \
public: \
inline C##Iterator(const C &container) \
: c(&container), i(c->constBegin()) {} \
inline C##Iterator &operator=(const C &container) \
{ c = &container; i = c->constBegin(); return *this; } \
inline void toFront() { i = c->constBegin(); } \
inline void toBack() { i = c->constEnd(); } \
inline bool hasNext() const { return i != c->constEnd(); } \
inline const T &next() { return *i++; } \
inline const T &peekNext() const { return *i; } \
inline bool hasPrevious() const { return i != c->constBegin(); } \
inline const T &previous() { return *--i; } \
inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
inline bool findNext(const T &t) \
{ while (i != c->constEnd()) if (*i++ == t) return true; return false; } \
inline bool findPrevious(const T &t) \
{ while (i != c->constBegin()) if (*(--i) == t) return true; \
return false; } \
};//C##Iterator
// Remove setShareable() from Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR
// Uses QHULL_ASSERT (assert.h)
// Duplicated in MutablePointIterator without insert or remove
// Not used in libqhullcpp. See Coordinates.h
#define QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C, T) \
class Mutable##C##Iterator \
{ \
typedef C::iterator iterator; \
typedef C::const_iterator const_iterator; \
C *c; \
iterator i, n; \
inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
public: \
inline Mutable##C##Iterator(C &container) \
: c(&container) \
{ i = c->begin(); n = c->end(); } \
inline ~Mutable##C##Iterator() \
{} \
inline Mutable##C##Iterator &operator=(C &container) \
{ c = &container; \
i = c->begin(); n = c->end(); return *this; } \
inline void toFront() { i = c->begin(); n = c->end(); } \
inline void toBack() { i = c->end(); n = i; } \
inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
inline T &next() { n = i++; return *n; } \
inline T &peekNext() const { return *i; } \
inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
inline T &previous() { n = --i; return *n; } \
inline T &peekPrevious() const { iterator p = i; return *--p; } \
inline void remove() \
{ if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
inline T &value() { QHULL_ASSERT(item_exists()); return *n; } \
inline const T &value() const { QHULL_ASSERT(item_exists()); return *n; } \
inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
inline bool findNext(const T &t) \
{ while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
inline bool findPrevious(const T &t) \
{ while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
n = c->end(); return false; } \
};//Mutable##C##Iterator
// Not used in libqhullcpp.
#define QHULL_DECLARE_SET_ITERATOR(C) \
\
template <class T> \
class Qhull##C##Iterator \
{ \
typedef typename Qhull##C<T>::const_iterator const_iterator; \
Qhull##C<T> c; \
const_iterator i; \
public: \
inline Qhull##C##Iterator(const Qhull##C<T> &container) \
: c(container), i(c.constBegin()) {} \
inline Qhull##C##Iterator &operator=(const Qhull##C<T> &container) \
{ c = container; i = c.constBegin(); return *this; } \
inline void toFront() { i = c.constBegin(); } \
inline void toBack() { i = c.constEnd(); } \
inline bool hasNext() const { return i != c.constEnd(); } \
inline const T &next() { return *i++; } \
inline const T &peekNext() const { return *i; } \
inline bool hasPrevious() const { return i != c.constBegin(); } \
inline const T &previous() { return *--i; } \
inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
inline bool findNext(const T &t) \
{ while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
inline bool findPrevious(const T &t) \
{ while (i != c.constBegin()) if (*(--i) == t) return true; \
return false; } \
};//Qhull##C##Iterator
// Not used in libqhullcpp.
#define QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) \
\
template <class T> \
class QhullMutable##C##Iterator \
{ \
typedef typename Qhull##C::iterator iterator; \
typedef typename Qhull##C::const_iterator const_iterator; \
Qhull##C *c; \
iterator i, n; \
inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
public: \
inline Mutable##C##Iterator(Qhull##C &container) \
: c(&container) \
{ c->setSharable(false); i = c->begin(); n = c->end(); } \
inline ~Mutable##C##Iterator() \
{ c->setSharable(true); } \
inline Mutable##C##Iterator &operator=(Qhull##C &container) \
{ c->setSharable(true); c = &container; c->setSharable(false); \
i = c->begin(); n = c->end(); return *this; } \
inline void toFront() { i = c->begin(); n = c->end(); } \
inline void toBack() { i = c->end(); n = i; } \
inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
inline T &next() { n = i++; return *n; } \
inline T &peekNext() const { return *i; } \
inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
inline T &previous() { n = --i; return *n; } \
inline T &peekPrevious() const { iterator p = i; return *--p; } \
inline void remove() \
{ if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
inline T &value() { Q_ASSERT(item_exists()); return *n; } \
inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
inline bool findNext(const T &t) \
{ while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
inline bool findPrevious(const T &t) \
{ while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
n = c->end(); return false; } \
};//QhullMutable##C##Iterator
}//namespace orgQhull
#endif // QHULLITERATOR_H

View File

@@ -0,0 +1,388 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullLinkedList.h#7 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLLINKEDLIST_H
#define QHULLLINKEDLIST_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullError.h"
#include <cstddef> // ptrdiff_t, size_t
#ifdef QHULL_USES_QT
#include <QtCore/QList>
#endif
#ifndef QHULL_NO_STL
#include <algorithm>
#include <iterator>
#include <vector>
#endif
namespace orgQhull {
#//!\name Defined here
//! QhullLinkedList<T> -- A linked list modeled on QLinkedList.
//! T is an opaque type with T(B *b), b=t.getBaseT(), t=t.next(), and t=t.prev(). The end node is a sentinel.
//! QhullQh/qhT owns the contents.
//! QhullLinkedList does not define erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList()
//! Derived from Qt/core/tools/qlinkedlist.h and libqhull_r.h/FORALLfacets_()
//! QhullLinkedList<T>::const_iterator -- STL-style iterator
//! QhullLinkedList<T>::iterator -- STL-style iterator
//! QhullLinkedListIterator<T> -- Java-style iterator
//! Derived from Qt/core/tools/qiterator.h
//! Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h]
template <typename T>
class QhullLinkedList
{
#//!\name Defined here
public:
class const_iterator;
class iterator;
typedef const_iterator ConstIterator;
typedef iterator Iterator;
typedef ptrdiff_t difference_type;
typedef countT size_type;
typedef T value_type;
typedef const value_type *const_pointer;
typedef const value_type &const_reference;
typedef value_type *pointer;
typedef value_type &reference;
#//!\name Fields
private:
T begin_node;
T end_node; //! Sentinel node at end of list
#//!\name Constructors
public:
QhullLinkedList<T>(T b, T e) : begin_node(b), end_node(e) {}
//! Copy constructor copies begin_node and end_node, but not the list elements. Needed for return by value and parameter passing.
QhullLinkedList<T>(const QhullLinkedList<T> &other) : begin_node(other.begin_node), end_node(other.end_node) {}
//! Copy assignment copies begin_node and end_node, but not the list elements.
QhullLinkedList<T> & operator=(const QhullLinkedList<T> &other) { begin_node= other.begin_node; end_node= other.end_node; return *this; }
~QhullLinkedList<T>() {}
private:
//!disabled since a sentinel must be allocated as the private type
QhullLinkedList<T>() {}
public:
#//!\name Conversions
#ifndef QHULL_NO_STL
std::vector<T> toStdVector() const;
#endif
#ifdef QHULL_USES_QT
QList<T> toQList() const;
#endif
#//!\name GetSet
countT count() const;
//count(t) under #//!\name Search
bool isEmpty() const { return (begin_node==end_node); }
bool operator==(const QhullLinkedList<T> &o) const;
bool operator!=(const QhullLinkedList<T> &o) const { return !operator==(o); }
size_t size() const { return count(); }
#//!\name Element access
//! For back() and last(), return T instead of T& (T is computed)
const T back() const { return last(); }
T back() { return last(); }
const T & first() const { QHULL_ASSERT(!isEmpty()); return begin_node; }
T & first() { QHULL_ASSERT(!isEmpty()); return begin_node; }
const T & front() const { return first(); }
T & front() { return first(); }
const T last() const { QHULL_ASSERT(!isEmpty()); return *--end(); }
T last() { QHULL_ASSERT(!isEmpty()); return *--end(); }
#//!\name Modify -- Allocation of opaque types not implemented.
#//!\name Search
bool contains(const T &t) const;
countT count(const T &t) const;
#//!\name Iterator
iterator begin() { return begin_node; }
const_iterator begin() const { return begin_node; }
const_iterator constBegin() const { return begin_node; }
const_iterator constEnd() const { return end_node; }
iterator end() { return end_node; }
const_iterator end() const { return end_node; }
class iterator {
private:
T i;
friend class const_iterator;
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef ptrdiff_t difference_type;
iterator() : i() {}
iterator(const T &t) : i(t) {} //!< Automatic conversion to iterator
iterator(const iterator &o) : i(o.i) {}
iterator & operator=(const iterator &o) { i= o.i; return *this; }
const T & operator*() const { return i; }
T & operator*() { return i; }
// Do not define operator[]
const T * operator->() const { return &i; }
T * operator->() { return &i; }
bool operator==(const iterator &o) const { return i == o.i; }
bool operator!=(const iterator &o) const { return !operator==(o); }
bool operator==(const const_iterator &o) const { return i==reinterpret_cast<const iterator &>(o).i; }
bool operator!=(const const_iterator &o) const { return !operator==(o); }
iterator & operator++() { i= i.next(); return *this; }
iterator operator++(int) { iterator o= i; i= i.next(); return o; }
iterator & operator--() { i= i.previous(); return *this; }
iterator operator--(int) { iterator o= i; i= i.previous(); return o; }
iterator operator+(int j) const;
iterator operator-(int j) const { return operator+(-j); }
iterator & operator+=(int j) { return (*this= *this + j); }
iterator & operator-=(int j) { return (*this= *this - j); }
};//QhullLinkedList::iterator
class const_iterator {
private:
T i;
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef const value_type *pointer;
typedef const value_type &reference;
typedef ptrdiff_t difference_type;
const_iterator() : i() {}
const_iterator(const T &t) : i(t) {} //!< Automatic conversion to const_iterator
const_iterator(const iterator &o) : i(o.i) {}
const_iterator(const const_iterator &o) : i(o.i) {}
const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; }
const T & operator*() const { return i; }
const T * operator->() const { return i; }
bool operator==(const const_iterator &o) const { return i == o.i; }
bool operator!=(const const_iterator &o) const { return !operator==(o); }
// No comparisons or iterator diff
const_iterator &operator++() { i= i.next(); return *this; }
const_iterator operator++(int) { const_iterator o= i; i= i.next(); return o; }
const_iterator &operator--() { i= i.previous(); return *this; }
const_iterator operator--(int) { const_iterator o= i; i= i.previous(); return o; }
const_iterator operator+(int j) const;
const_iterator operator-(int j) const { return operator+(-j); }
const_iterator &operator+=(int j) { return (*this= *this + j); }
const_iterator &operator-=(int j) { return (*this= *this - j); }
};//QhullLinkedList::const_iterator
};//QhullLinkedList
template <typename T>
class QhullLinkedListIterator // FIXUP QH11016 define QhullMutableLinkedListIterator
{
typedef typename QhullLinkedList<T>::const_iterator const_iterator;
const QhullLinkedList<T> *c;
const_iterator i;
public:
QhullLinkedListIterator(const QhullLinkedList<T> &container) : c(&container), i(c->constBegin()) {}
QhullLinkedListIterator & operator=(const QhullLinkedList<T> &container) { c= &container; i= c->constBegin(); return *this; }
bool findNext(const T &t);
bool findPrevious(const T &t);
bool hasNext() const { return i != c->constEnd(); }
bool hasPrevious() const { return i != c->constBegin(); }
T next() { return *i++; }
T peekNext() const { return *i; }
T peekPrevious() const { const_iterator p= i; return *--p; }
T previous() { return *--i; }
void toFront() { i= c->constBegin(); }
void toBack() { i= c->constEnd(); }
};//QhullLinkedListIterator
#//!\name == Definitions =========================================
#//!\name Conversion
#ifndef QHULL_NO_STL
template <typename T>
std::vector<T> QhullLinkedList<T>::
toStdVector() const
{
std::vector<T> tmp;
std::copy(constBegin(), constEnd(), std::back_inserter(tmp));
return tmp;
}//toStdVector
#endif
#ifdef QHULL_USES_QT
template <typename T>
QList<T> QhullLinkedList<T>::
toQList() const
{
QhullLinkedListIterator<T> i(*this);
QList<T> ls;
while(i.hasNext()){
ls.append(i.next());
}
return ls;
}//toQList
#endif
#//!\name GetSet
template <typename T>
countT QhullLinkedList<T>::
count() const
{
const_iterator i= begin_node;
countT c= 0;
while(i != end_node){
c++;
i++;
}
return c;
}//count
#//!\name Search
template <typename T>
bool QhullLinkedList<T>::
contains(const T &t) const
{
const_iterator i= begin_node;
while(i != end_node){
if(i==t){
return true;
}
i++;
}
return false;
}//contains
template <typename T>
countT QhullLinkedList<T>::
count(const T &t) const
{
const_iterator i= begin_node;
countT c= 0;
while(i != end_node){
if(i==t){
c++;
}
i++;
}
return c;
}//count
template <typename T>
bool QhullLinkedList<T>::
operator==(const QhullLinkedList<T> &l) const
{
if(begin_node==l.begin_node){
return (end_node==l.end_node);
}
T i= begin_node;
T il= l.begin_node;
while(i != end_node){
if(i != il){
return false;
}
i= static_cast<T>(i.next());
il= static_cast<T>(il.next());
}
if(il != l.end_node){
return false;
}
return true;
}//operator==
#//!\name Iterator
template <typename T>
typename QhullLinkedList<T>::iterator QhullLinkedList<T>::iterator::
operator+(int j) const
{
T n= i;
if(j>0){
while(j--){
n= n.next();
}
}else{
while(j++){
n= n.previous();
}
}
return iterator(n);
}//operator+
template <typename T>
typename QhullLinkedList<T>::const_iterator QhullLinkedList<T>::const_iterator::
operator+(int j) const
{
T n= i;
if(j>0){
while(j--){
n= n.next();
}
}else{
while(j++){
n= n.previous();
}
}
return const_iterator(n);
}//operator+
#//!\name QhullLinkedListIterator
template <typename T>
bool QhullLinkedListIterator<T>::
findNext(const T &t)
{
while(i != c->constEnd()){
if (*i++ == t){
return true;
}
}
return false;
}//findNext
template <typename T>
bool QhullLinkedListIterator<T>::
findPrevious(const T &t)
{
while(i!=c->constBegin()){
if(*(--i)==t){
return true;
}
}
return false;
}//findNext
}//namespace orgQhull
#//!\name Global
template <typename T>
std::ostream &
operator<<(std::ostream &os, const orgQhull::QhullLinkedList<T> &qs)
{
typename orgQhull::QhullLinkedList<T>::const_iterator i;
for(i= qs.begin(); i != qs.end(); ++i){
os << *i;
}
return os;
}//operator<<
#endif // QHULLLINKEDLIST_H

View File

@@ -0,0 +1,203 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoint.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/Qhull.h"
#include <iostream>
#include <algorithm>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Constructors
QhullPoint::
QhullPoint(const Qhull &q)
: point_coordinates(0)
, qh_qh(q.qh())
, point_dimension(q.hullDimension())
{
}//QhullPoint
QhullPoint::
QhullPoint(const Qhull &q, coordT *c)
: point_coordinates(c)
, qh_qh(q.qh())
, point_dimension(q.hullDimension())
{
QHULL_ASSERT(q.hullDimension()>0);
}//QhullPoint dim, coordT
QhullPoint::
QhullPoint(const Qhull &q, int pointDimension, coordT *c)
: point_coordinates(c)
, qh_qh(q.qh())
, point_dimension(pointDimension)
{
}//QhullPoint dim, coordT
//! QhullPoint of Coordinates with point_dimension==c.count()
QhullPoint::
QhullPoint(const Qhull &q, Coordinates &c)
: point_coordinates(c.data())
, qh_qh(q.qh())
, point_dimension(c.count())
{
}//QhullPoint Coordinates
#//!\name Conversions
// See qt-qhull.cpp for QList conversion
#ifndef QHULL_NO_STL
std::vector<coordT> QhullPoint::
toStdVector() const
{
QhullPointIterator i(*this);
std::vector<coordT> vs;
while(i.hasNext()){
vs.push_back(i.next());
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
//! QhullPoint is equal if it has the same address and dimension
//! If !qh_qh, returns true if dimension and coordinates are equal
//! If qh_qh, returns true if the distance between points is less than qh_qh->distanceEpsilon()
//!\todo Compares distance with distance-to-hyperplane (distanceEpsilon). Is that correct?
bool QhullPoint::
operator==(const QhullPoint &other) const
{
if(point_dimension!=other.point_dimension){
return false;
}
const coordT *c= point_coordinates;
const coordT *c2= other.point_coordinates;
if(c==c2){
return true;
}
if(!c || !c2){
return false;
}
if(!qh_qh || qh_qh->hull_dim==0){
for(int k= point_dimension; k--; ){
if(*c++ != *c2++){
return false;
}
}
return true;
}
double dist2= 0.0;
for(int k= point_dimension; k--; ){
double diff= *c++ - *c2++;
dist2 += diff*diff;
}
dist2= sqrt(dist2);
return (dist2 < qh_qh->distanceEpsilon());
}//operator==
#//!\name Methods
//! Return distance between two points.
double QhullPoint::
distance(const QhullPoint &p) const
{
const coordT *c= point_coordinates;
const coordT *c2= p.point_coordinates;
int dim= point_dimension;
if(dim!=p.point_dimension){
throw QhullError(10075, "QhullPoint error: Expecting dimension %d for distance(). Got %d", dim, p.point_dimension);
}
if(!c || !c2){
throw QhullError(10076, "QhullPoint error: Cannot compute distance() for undefined point");
}
double dist;
switch(dim){
case 2:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]);
break;
case 3:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]);
break;
case 4:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]);
break;
case 5:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]);
break;
case 6:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]);
break;
case 7:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]);
break;
case 8:
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]) + (c[7]-c2[7])*(c[7]-c2[7]);
break;
default:
dist= 0.0;
for(int k=dim; k--; ){
dist += (*c - *c2) * (*c - *c2);
++c;
++c2;
}
break;
}
return sqrt(dist);
}//distance
}//namespace orgQhull
#//!\name Global functions
using std::ostream;
using orgQhull::QhullPoint;
//! Same as qh_printpointid [io.c]
ostream &
operator<<(ostream &os, const QhullPoint::PrintPoint &pr)
{
QhullPoint p= *pr.point;
countT i= p.id();
if(pr.point_message){
if(*pr.point_message){
os << pr.point_message << " ";
}
if(pr.with_identifier && (i!=qh_IDunknown) && (i!=qh_IDnone)){
os << "p" << i << ": ";
}
}
const realT *c= p.coordinates();
for(int k=p.dimension(); k--; ){
realT r= *c++;
if(pr.point_message){
os << " " << r; // FIXUP QH11010 %8.4g
}else{
os << " " << r; // FIXUP QH11010 qh_REAL_1
}
}
os << std::endl;
return os;
}//printPoint
ostream &
operator<<(ostream &os, const QhullPoint &p)
{
os << p.print("");
return os;
}//operator<<

View File

@@ -0,0 +1,136 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoint.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHPOINT_H
#define QHPOINT_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullIterator.h"
#include "libqhullcpp/QhullQh.h"
#include "libqhullcpp/Coordinates.h"
#include <ostream>
namespace orgQhull {
#//!\name Defined here
class QhullPoint; //!< QhullPoint as a pointer and dimension to shared memory
class QhullPointIterator; //!< Java-style iterator for QhullPoint coordinates
#//!\name Used here
class Qhull;
//! A QhullPoint is a dimension and an array of coordinates.
//! With Qhull/QhullQh, a QhullPoint has an identifier. Point equality is relative to qh.distanceEpsilon
class QhullPoint {
#//!\name Iterators
public:
typedef coordT * base_type; // for QhullPointSet
typedef const coordT * iterator;
typedef const coordT * const_iterator;
typedef QhullPoint::iterator Iterator;
typedef QhullPoint::const_iterator ConstIterator;
#//!\name Fields
protected: // For QhullPoints::iterator, QhullPoints::const_iterator
coordT * point_coordinates; //!< Pointer to first coordinate, 0 if undefined
QhullQh * qh_qh; //!< qhT for this instance of Qhull. 0 if undefined.
//!< operator==() returns true if points within sqrt(qh_qh->distanceEpsilon())
//!< If !qh_qh, id() is -3, and operator==() requires equal coordinates
int point_dimension; //!< Default dimension is qh_qh->hull_dim
public:
#//!\name Constructors
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
//! If Qhull/QhullQh is not initialized, then QhullPoint.dimension() is zero unless explicitly set
//! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
QhullPoint() : point_coordinates(0), qh_qh(0), point_dimension(0) {}
QhullPoint(int pointDimension, coordT *c) : point_coordinates(c), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>0); }
explicit QhullPoint(const Qhull &q);
QhullPoint(const Qhull &q, coordT *c);
QhullPoint(const Qhull &q, Coordinates &c);
QhullPoint(const Qhull &q, int pointDimension, coordT *c);
explicit QhullPoint(QhullQh *qqh) : point_coordinates(0), qh_qh(qqh), point_dimension(qqh->hull_dim) {}
QhullPoint(QhullQh *qqh, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(qqh->hull_dim) { QHULL_ASSERT(qqh->hull_dim>0); }
QhullPoint(QhullQh *qqh, Coordinates &c) : point_coordinates(c.data()), qh_qh(qqh), point_dimension(c.count()) {}
QhullPoint(QhullQh *qqh, int pointDimension, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(pointDimension) {}
//! Creates an alias. Does not make a deep copy of the point. Needed for return by value and parameter passing.
QhullPoint(const QhullPoint &other) : point_coordinates(other.point_coordinates), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
//! Creates an alias. Does not make a deep copy of the point. Needed for vector<QhullPoint>
QhullPoint & operator=(const QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
~QhullPoint() {}
#//!\name Conversions
#ifndef QHULL_NO_STL
std::vector<coordT> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
public:
const coordT * coordinates() const { return point_coordinates; } //!< 0 if undefined
coordT * coordinates() { return point_coordinates; } //!< 0 if undefined
void defineAs(coordT *c) { QHULL_ASSERT(point_dimension>0); point_coordinates= c; }
void defineAs(int pointDimension, coordT *c) { QHULL_ASSERT(pointDimension>=0); point_coordinates= c; point_dimension= pointDimension; }
void defineAs(QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
int dimension() const { return point_dimension; }
coordT * getBaseT() const { return point_coordinates; } // for QhullPointSet
countT id() const { return qh_pointid(qh_qh, point_coordinates); } // NOerrors
bool isValid() const { return (point_coordinates!=0 && point_dimension>0); };
bool operator==(const QhullPoint &other) const;
bool operator!=(const QhullPoint &other) const { return ! operator==(other); }
const coordT & operator[](int idx) const { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
coordT & operator[](int idx) { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
QhullQh * qh() { return qh_qh; }
void setCoordinates(coordT *c) { point_coordinates= c; }
void setDimension(int pointDimension) { point_dimension= pointDimension; }
#//!\name foreach
iterator begin() { return point_coordinates; }
const_iterator begin() const { return point_coordinates; }
const_iterator constBegin() const { return point_coordinates; }
const_iterator constEnd() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
int count() { return (point_coordinates ? point_dimension : 0); }
iterator end() { return (point_coordinates ? point_coordinates+point_dimension : 0); }
const_iterator end() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
size_t size() { return (size_t)(point_coordinates ? point_dimension : 0); }
#//!\name Methods
void advancePoint(countT idx) { if(point_coordinates) { point_coordinates += idx*point_dimension; } }
double distance(const QhullPoint &p) const;
#//!\name IO
struct PrintPoint{
const QhullPoint *point;
const char * point_message;
bool with_identifier;
PrintPoint(const char *message, bool withIdentifier, const QhullPoint &p) : point(&p), point_message(message), with_identifier(withIdentifier) {}
};//PrintPoint
PrintPoint print(const char *message) const { return PrintPoint(message, false, *this); }
PrintPoint printWithIdentifier(const char *message) const { return PrintPoint(message, true, *this); }
};//QhullPoint
QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullPoint, coordT)
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint::PrintPoint &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint &p);
#endif // QHPOINT_H

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullPointSet.cpp#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/QhullPointSet.h"
#include <iostream>
#include <algorithm>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
// Implemented via QhullSet.h
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullPoint;
using orgQhull::QhullPointSet;
using orgQhull::QhullPointSetIterator;
ostream &
operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr)
{
os << pr.print_message;
const QhullPointSet s= *pr.point_set;
QhullPointSetIterator i(s);
while(i.hasNext()){
if(i.hasPrevious()){
os << " ";
}
const QhullPoint point= i.next();
countT id= point.id();
os << "p" << id;
}
os << endl;
return os;
}//PrintIdentifiers
ostream &
operator<<(ostream &os, const QhullPointSet::PrintPointSet &pr)
{
os << pr.print_message;
const QhullPointSet s= *pr.point_set;
for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
const QhullPoint point= *i;
os << point;
}
return os;
}//printPointSet

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullPointSet.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLPOINTSET_H
#define QHULLPOINTSET_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullPoint.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Qhull;
class QhullPoint;
#//!\name Defined here
//! QhullPointSet -- a set of coordinate pointers with input dimension
// with const_iterator and iterator
class QhullPointSet;
class QhullPointSet : public QhullSet<QhullPoint> {
private:
#//!\name Fields
// no fields
public:
#//!\name Construct
QhullPointSet(const Qhull &q, setT *s) : QhullSet<QhullPoint>(q, s) {}
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
QhullPointSet(QhullQh *qqh, setT *s) : QhullSet<QhullPoint>(qqh, s) {}
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
QhullPointSet(const QhullPointSet &other) : QhullSet<QhullPoint>(other) {}
//!Assignment copies pointers but not contents.
QhullPointSet & operator=(const QhullPointSet &other) { QhullSet<QhullPoint>::operator=(other); return *this; }
~QhullPointSet() {}
//!Default constructor disabled.
private:
QhullPointSet();
public:
#//!\name IO
struct PrintIdentifiers{
const QhullPointSet *point_set;
const char * print_message; //!< non-null message
PrintIdentifiers(const char *message, const QhullPointSet *s) : point_set(s), print_message(message) {}
};//PrintIdentifiers
PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
struct PrintPointSet{
const QhullPointSet *point_set;
const char * print_message; //!< non-null message
PrintPointSet(const char *message, const QhullPointSet &s) : point_set(&s), print_message(message) {}
};//PrintPointSet
PrintPointSet print(const char *message) const { return PrintPointSet(message, *this); }
};//QhullPointSet
typedef QhullSetIterator<QhullPoint> QhullPointSetIterator;
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintIdentifiers &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintPointSet &pr);
#endif // QHULLPOINTSET_H

View File

@@ -0,0 +1,320 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoints.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/QhullPoints.h"
#include "libqhullcpp/Qhull.h"
#include <iostream>
#ifndef QHULL_NO_STL
#include <vector>
#endif
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Constructors
QhullPoints::
QhullPoints(const Qhull &q)
: point_first(0)
, point_end(0)
, qh_qh(q.qh())
, point_dimension(q.hullDimension())
{
}//QhullPoints Qhull
QhullPoints::
QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c)
: point_first(c)
, point_end(c+coordinateCount2)
, qh_qh(q.qh())
, point_dimension(q.hullDimension())
{
QHULL_ASSERT(q.hullDimension());
QHULL_ASSERT(coordinateCount2>=0);
}//QhullPoints Qhull dim
QhullPoints::
QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c)
: point_first(c)
, point_end(c+coordinateCount2)
, qh_qh(q.qh())
, point_dimension(pointDimension)
{
QHULL_ASSERT(pointDimension>=0);
QHULL_ASSERT(coordinateCount2>=0);
}//QhullPoints Qhull dim coordT
QhullPoints::
QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c)
: point_first(c)
, point_end(c+coordinateCount2)
, qh_qh(qqh)
, point_dimension(pointDimension)
{
QHULL_ASSERT(pointDimension>=0);
QHULL_ASSERT(coordinateCount2>=0);
}//QhullPoints QhullQh dim coordT
#//!\name Conversions
// See qt-qhull.cpp for QList conversion
#ifndef QHULL_NO_STL
std::vector<QhullPoint> QhullPoints::
toStdVector() const
{
QhullPointsIterator i(*this);
std::vector<QhullPoint> vs;
while(i.hasNext()){
vs.push_back(i.next());
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
countT QhullPoints::
extraCoordinatesCount() const
{
if(point_dimension>0){
return (countT)((point_end-point_first)%(size_t)point_dimension);
}
return 0;
}//extraCoordinatesCount
//! QhullPoints is equal if the same address, or if the coordinates are identical
//! Use QhullPoint.operator==() for DISTround equality
bool QhullPoints::
operator==(const QhullPoints &other) const
{
if((point_end-point_first) != (other.point_end-other.point_first)){
return false;
}
if(point_dimension!=other.point_dimension){
return false;
}
if(point_first==other.point_first){
return true;
}
if(!qh_qh || qh_qh->hull_dim==0){
const coordT *c= point_first;
const coordT *c2= other.point_first;
while(c<point_end){
if(*c++!=*c2++){
return false;
}
}
}else{
const_iterator i= begin();
const_iterator i2= other.begin();
while(i<end()){
if(*i++!=*i2++){
return false;
}
}
}
return true;
}//operator==
//! Reset QhullPoints to QhullQh and its hullDimension()
//! Does not free up old qh_qh
void QhullPoints::
resetQhullQh(QhullQh *qqh)
{
qh_qh= qqh;
point_dimension= (qqh ? qqh->hull_dim : 0);
point_first= 0;
point_end= 0;
}//resetQhullQh
QhullPoint QhullPoints::
value(countT idx) const
{
QhullPoint p(qh_qh);
if(idx>=0 && idx<count()){
p.defineAs(point_dimension, point_first+idx*point_dimension);
}
return p;
}//value
QhullPoint QhullPoints::
value(countT idx, QhullPoint &defaultValue) const
{
QhullPoint p(qh_qh);
if(idx>=0 && idx<count()){
p.defineAs(point_dimension, point_first+idx*point_dimension);
}else{
p.defineAs(defaultValue);
}
return p;
}//value
#//!\name Methods
bool QhullPoints::
contains(const QhullPoint &t) const
{
const_iterator i= begin();
while(i != end()){
if(*i==t){
return true;
}
i++;
}
return false;
}//contains
countT QhullPoints::
count(const QhullPoint &t) const
{
countT n= 0;
const_iterator i= begin();
while(i != end()){
if(*i==t){
++n;
}
i++;
}
return n;
}//count
countT QhullPoints::
indexOf(const coordT *pointCoordinates) const
{
if(!includesCoordinates(pointCoordinates) || point_dimension==0){
return -1;
}
size_t offset= pointCoordinates-point_first;
countT idx= (countT)(offset/(size_t)point_dimension);
countT extra= (countT)(offset%(size_t)point_dimension);
if(extra!=0){
throw QhullError(10066, "Qhull error: coordinates %x are not at point boundary (extra %d at index %d)", extra, idx, 0.0, pointCoordinates);
}
return idx;
}//indexOf coordT
countT QhullPoints::
indexOf(const coordT *pointCoordinates, int noThrow) const
{
size_t extra= 0;
if(noThrow){
if(!includesCoordinates(pointCoordinates) || point_dimension==0){
return -1;
}
extra= (pointCoordinates-point_first)%(size_t)point_dimension;
}
return indexOf(pointCoordinates-extra);
}//indexOf coordT noThrow
countT QhullPoints::
indexOf(const QhullPoint &t) const
{
countT j=0;
const_iterator i= begin();
while(i!=end()){
if(*i==t){
return j;
}
++i;
++j;
}
return -1;
}//indexOf
countT QhullPoints::
lastIndexOf(const QhullPoint &t) const
{
countT j= count();
const_iterator i= end();
while(i != begin()){
--i;
--j;
if(*i==t){
return j;
}
}
return -1;
}//lastIndexOf
QhullPoints QhullPoints::
mid(countT idx, countT length) const
{
countT n= count();
if(idx<0 || idx>=n){
n= 0;
}else if(length<0 || idx+length>=n){
n -= idx;
}else{
n -= idx+length;
}
return QhullPoints(qh_qh, point_dimension, n*point_dimension, point_first+idx*point_dimension);
}//mid
#//!\name QhullPointsIterator
bool QhullPointsIterator::
findNext(const QhullPoint &p)
{
while(i!=ps->constEnd()){
if(*i++ == p){
return true;
}
}
return false;
}//findNext
bool QhullPointsIterator::
findPrevious(const QhullPoint &p)
{
while(i!=ps->constBegin()){
if(*--i == p){
return true;
}
}
return false;
}//findPrevious
}//namespace orgQhull
#//!\name Global functions
using std::ostream;
using orgQhull::QhullPoint;
using orgQhull::QhullPoints;
using orgQhull::QhullPointsIterator;
ostream &
operator<<(ostream &os, const QhullPoints &p)
{
QhullPointsIterator i(p);
while(i.hasNext()){
os << i.next();
}
return os;
}//operator<<QhullPoints
ostream &
operator<<(ostream &os, const QhullPoints::PrintPoints &pr)
{
os << pr.point_message;
QhullPoints ps= *pr.points;
for(QhullPoints::iterator i=ps.begin(); i!=ps.end(); ++i){
QhullPoint p= *i;
if(pr.with_identifier){
os << p.printWithIdentifier("");
}else{
os << p.print("");
}
}
return os;
}//<<PrintPoints

View File

@@ -0,0 +1,266 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoints.h#5 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLPOINTS_H
#define QHULLPOINTS_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullPoint.h"
#include <cstddef> // ptrdiff_t, size_t
#include <ostream>
namespace orgQhull {
#//!\name Defined here
class QhullPoints; //!< One or more points Coordinate pointers with dimension and iterators
class QhullPointsIterator; //!< Java-style iterator
//! QhullPoints are an array of QhullPoint as pointers into an array of coordinates.
//! For Qhull/QhullQh, QhullPoints must use hull_dim. Can change QhullPoint to input_dim if needed for Delaunay input site
class QhullPoints {
private:
#//!\name Fields
coordT * point_first; //!< First coordinate of an array of points of point_dimension
coordT * point_end; //!< End of point coordinates (end>=first). Trailing coordinates ignored
QhullQh * qh_qh; //!< Maybe initialized NULL to allow ownership by RboxPoints
//!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor
int point_dimension; //!< Dimension, >=0
public:
#//!\name Subtypes
class const_iterator;
class iterator;
typedef QhullPoints::const_iterator ConstIterator;
typedef QhullPoints::iterator Iterator;
#//!\name Construct
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
//! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set
//! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { }
QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
explicit QhullPoints(const Qhull &q);
QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c);
QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c);
explicit QhullPoints(QhullQh *qqh) : point_first(0), point_end(0), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { }
QhullPoints(QhullQh *qqh, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { QHULL_ASSERT(qqh && qqh->hull_dim>0); }
QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c);
//! Copy constructor copies pointers but not contents. Needed for return by value and parameter passing.
QhullPoints(const QhullPoints &other) : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
QhullPoints & operator=(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
~QhullPoints() {}
public:
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<QhullPoint> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullPoint> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
// Constructs QhullPoint. Cannot return reference.
const QhullPoint at(countT idx) const { /* point_first==0 caught by point_end assert */ coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p<point_end); return QhullPoint(qh_qh, point_dimension, p); }
// Constructs QhullPoint. Cannot return reference.
const QhullPoint back() const { return last(); }
QhullPoint back() { return last(); }
ConstIterator begin() const { return ConstIterator(*this); }
Iterator begin() { return Iterator(*this); }
ConstIterator constBegin() const { return ConstIterator(*this); }
const coordT * constData() const { return point_first; }
ConstIterator constEnd() const { return ConstIterator(qh_qh, point_dimension, point_end); }
coordT * coordinates() const { return point_first; }
countT coordinateCount() const { return (countT)(point_end-point_first); } // WARN64
countT count() const { return (countT)size(); } // WARN64
const coordT * data() const { return point_first; }
coordT * data() { return point_first; }
void defineAs(int pointDimension, countT coordinatesCount, coordT *c) { QHULL_ASSERT(pointDimension>=0 && coordinatesCount>=0 && c!=0); point_first= c; point_end= c+coordinatesCount; point_dimension= pointDimension; }
void defineAs(countT coordinatesCount, coordT *c) { QHULL_ASSERT((point_dimension>0 && coordinatesCount>=0 && c!=0) || (c==0 && coordinatesCount==0)); point_first= c; point_end= c+coordinatesCount; }
void defineAs(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
int dimension() const { return point_dimension; }
ConstIterator end() const { return ConstIterator(qh_qh, point_dimension, point_end); }
Iterator end() { return Iterator(qh_qh, point_dimension, point_end); }
coordT * extraCoordinates() const { return extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0; }
countT extraCoordinatesCount() const; // WARN64
// Constructs QhullPoint. Cannot return reference.
const QhullPoint first() const { return QhullPoint(qh_qh, point_dimension, point_first); }
QhullPoint first() { return QhullPoint(qh_qh, point_dimension, point_first); }
// Constructs QhullPoint. Cannot return reference.
const QhullPoint front() const { return first(); }
QhullPoint front() { return first(); }
bool includesCoordinates(const coordT *c) const { return c>=point_first && c<point_end; }
bool isEmpty() const { return (point_end==point_first || point_dimension==0); }
// Constructs QhullPoint. Cannot return reference.
const QhullPoint last() const { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
QhullPoint last() { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
bool operator==(const QhullPoints &other) const;
bool operator!=(const QhullPoints &other) const { return ! operator==(other); }
QhullPoint operator[](countT idx) const { return at(idx); }
QhullQh * qh() const { return qh_qh; }
void resetQhullQh(QhullQh *qqh);
void setDimension(int d) { point_dimension= d; }
size_t size() const { return point_dimension ? (point_end-point_first)/point_dimension : 0; }
QhullPoint value(countT idx) const;
QhullPoint value(countT idx, QhullPoint &defaultValue) const;
#//!\name Methods
bool contains(const QhullPoint &t) const;
countT count(const QhullPoint &t) const;
countT indexOf(const coordT *pointCoordinates) const;
countT indexOf(const coordT *pointCoordinates, int noThrow) const;
countT indexOf(const QhullPoint &t) const;
countT lastIndexOf(const QhullPoint &t) const;
//! Returns a subset of the points, not a copy
QhullPoints mid(countT idx, countT length= -1) const;
#//!\name QhullPoints::iterator
// Modeled on qlist.h w/o QT_STRICT_ITERATORS
// before const_iterator for conversion with comparison operators
// See: QhullSet.h
class iterator : public QhullPoint {
public:
typedef std::random_access_iterator_tag iterator_category;
typedef QhullPoint value_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef ptrdiff_t difference_type;
explicit iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
iterator(const iterator &other): QhullPoint(*other) {}
iterator & operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; }
// Need 'const QhullPoint' to maintain const
const QhullPoint & operator*() const { return *this; }
QhullPoint & operator*() { return *this; }
const QhullPoint * operator->() const { return this; }
QhullPoint * operator->() { return this; }
// value instead of reference since advancePoint() modifies self
QhullPoint operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; }
bool operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
bool operator!=(const iterator &o) const { return !operator==(o); }
bool operator<(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
bool operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
bool operator>(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
bool operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
// reinterpret_cast to break circular dependency
bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return (point_coordinates==reinterpret_cast<const iterator &>(o).point_coordinates && point_dimension==reinterpret_cast<const iterator &>(o).point_dimension); }
bool operator!=(const QhullPoints::const_iterator &o) const { return !operator==(reinterpret_cast<const iterator &>(o)); }
bool operator<(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates < reinterpret_cast<const iterator &>(o).point_coordinates; }
bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates <= reinterpret_cast<const iterator &>(o).point_coordinates; }
bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates > reinterpret_cast<const iterator &>(o).point_coordinates; }
bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates >= reinterpret_cast<const iterator &>(o).point_coordinates; }
iterator & operator++() { advancePoint(1); return *this; }
iterator operator++(int) { iterator n= *this; operator++(); return iterator(n); }
iterator & operator--() { advancePoint(-1); return *this; }
iterator operator--(int) { iterator n= *this; operator--(); return iterator(n); }
iterator & operator+=(countT idx) { advancePoint(idx); return *this; }
iterator & operator-=(countT idx) { advancePoint(-idx); return *this; }
iterator operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; }
iterator operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; }
difference_type operator-(iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
};//QhullPoints::iterator
#//!\name QhullPoints::const_iterator
//!\todo FIXUP QH11018 const_iterator same as iterator. SHould have a common definition
class const_iterator : public QhullPoint {
public:
typedef std::random_access_iterator_tag iterator_category;
typedef QhullPoint value_type;
typedef const value_type * pointer;
typedef const value_type & reference;
typedef ptrdiff_t difference_type;
const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {}
explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
const_iterator(const const_iterator &o) : QhullPoint(*o) {}
const_iterator &operator=(const const_iterator &o) { defineAs(const_cast<const_iterator &>(o)); return *this; }
// value/non-const since advancePoint(1), etc. modifies self
const QhullPoint & operator*() const { return *this; }
const QhullPoint * operator->() const { return this; }
// value instead of reference since advancePoint() modifies self
const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
bool operator==(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
bool operator!=(const const_iterator &o) const { return ! operator==(o); }
bool operator<(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
bool operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
bool operator>(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
bool operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
const_iterator &operator++() { advancePoint(1); return *this; }
const_iterator operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); }
const_iterator &operator--() { advancePoint(-1); return *this; }
const_iterator operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); }
const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; }
const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; }
const_iterator operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; }
const_iterator operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; }
difference_type operator-(const_iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
};//QhullPoints::const_iterator
#//!\name IO
struct PrintPoints{
const QhullPoints *points;
const char * point_message;
bool with_identifier;
PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {}
};//PrintPoints
PrintPoints print(const char *message) const { return PrintPoints(message, false, *this); }
PrintPoints printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); }
};//QhullPoints
// Instead of QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc would return a reference to a temporary
class QhullPointsIterator
{
typedef QhullPoints::const_iterator const_iterator;
#//!\name Fields
private:
const QhullPoints *ps;
const_iterator i;
public:
QhullPointsIterator(const QhullPoints &other) : ps(&other), i(ps->constBegin()) {}
QhullPointsIterator &operator=(const QhullPoints &other) { ps = &other; i = ps->constBegin(); return *this; }
bool findNext(const QhullPoint &t);
bool findPrevious(const QhullPoint &t);
bool hasNext() const { return i != ps->constEnd(); }
bool hasPrevious() const { return i != ps->constBegin(); }
QhullPoint next() { return *i++; }
QhullPoint peekNext() const { return *i; }
QhullPoint peekPrevious() const { const_iterator p = i; return *--p; }
QhullPoint previous() { return *--i; }
void toBack() { i = ps->constEnd(); }
void toFront() { i = ps->constBegin(); }
};//QhullPointsIterator
}//namespace orgQhull
#//!\name Global
std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints &p);
std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr);
#endif // QHULLPOINTS_H

View File

@@ -0,0 +1,237 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.cpp#5 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
#include "libqhullcpp/QhullQh.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullStat.h"
#include <sstream>
#include <iostream>
#include <stdarg.h>
using std::cerr;
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 {
#//!\name Global variables
const double QhullQh::
default_factor_epsilon= 1.0;
#//!\name Constructor, destructor, etc.
//! Derived from qh_new_qhull[user.c]
QhullQh::
QhullQh()
: qhull_status(qh_ERRnone)
, qhull_message()
, error_stream(0)
, output_stream(0)
, factor_epsilon(QhullQh::default_factor_epsilon)
, use_output_stream(false)
{
// NOerrors: TRY_QHULL_ not needed since these routines do not call qh_errexit()
qh_meminit(this, NULL);
qh_initstatistics(this);
qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr); // Initialize qhT
this->ISqhullQh= True;
}//QhullQh
QhullQh::
~QhullQh()
{
checkAndFreeQhullMemory();
}//~QhullQh
#//!\name Methods
//! Check memory for internal consistency
//! Free global memory used by qh_initbuild and qh_buildhull
//! Zero the qhT data structure, except for memory (qhmemT) and statistics (qhstatT)
//! Check and free short memory (e.g., facetT)
//! Zero the qhmemT data structure
void QhullQh::
checkAndFreeQhullMemory()
{
#ifdef qh_NOmem
qh_freeqhull(this, qh_ALL);
#else
qh_memcheck(this);
qh_freeqhull(this, !qh_ALL);
countT curlong;
countT totlong;
qh_memfreeshort(this, &curlong, &totlong);
if (curlong || totlong)
throw QhullError(10026, "Qhull error: qhull did not free %d bytes of long memory (%d pieces).", totlong, curlong);
#endif
}//checkAndFreeQhullMemory
#//!\name Messaging
void QhullQh::
appendQhullMessage(const string &s)
{
if(output_stream && use_output_stream && this->USEstdout){
*output_stream << s;
}else if(error_stream){
*error_stream << s;
}else{
qhull_message += s;
}
}//appendQhullMessage
//! clearQhullMessage does not throw errors (~Qhull)
void QhullQh::
clearQhullMessage()
{
qhull_status= qh_ERRnone;
qhull_message.clear();
RoadError::clearGlobalLog();
}//clearQhullMessage
//! hasQhullMessage does not throw errors (~Qhull)
bool QhullQh::
hasQhullMessage() const
{
return (!qhull_message.empty() || qhull_status!=qh_ERRnone);
//FIXUP QH11006 -- inconsistent usage with Rbox. hasRboxMessage just tests rbox_status. No appendRboxMessage()
}
void QhullQh::
maybeThrowQhullMessage(int exitCode)
{
if(!NOerrexit){
if(qhull_message.size()>0){
qhull_message.append("\n");
}
if(exitCode || qhull_status==qh_ERRnone){
qhull_status= 10073;
}else{
qhull_message.append("QH10073: ");
}
qhull_message.append("Cannot call maybeThrowQhullMessage() from QH_TRY_(). Or missing 'qh->NOerrexit=true;' after QH_TRY_(){...}.");
}
if(qhull_status==qh_ERRnone){
qhull_status= exitCode;
}
if(qhull_status!=qh_ERRnone){
QhullError e(qhull_status, qhull_message);
clearQhullMessage();
throw e; // FIXUP QH11007: copy constructor is expensive if logging
}
}//maybeThrowQhullMessage
void QhullQh::
maybeThrowQhullMessage(int exitCode, int noThrow) throw()
{
QHULL_UNUSED(noThrow);
if(qhull_status==qh_ERRnone){
qhull_status= exitCode;
}
if(qhull_status!=qh_ERRnone){
QhullError e(qhull_status, qhull_message);
e.logErrorLastResort();
}
}//maybeThrowQhullMessage
//! qhullMessage does not throw errors (~Qhull)
std::string QhullQh::
qhullMessage() const
{
if(qhull_message.empty() && qhull_status!=qh_ERRnone){
return "qhull: no message for error. Check cerr or error stream\n";
}else{
return qhull_message;
}
}//qhullMessage
int QhullQh::
qhullStatus() const
{
return qhull_status;
}//qhullStatus
void QhullQh::
setErrorStream(ostream *os)
{
error_stream= os;
}//setErrorStream
//! Updates use_output_stream
void QhullQh::
setOutputStream(ostream *os)
{
output_stream= os;
use_output_stream= (os!=0);
}//setOutputStream
}//namespace orgQhull
/*-<a href="qh_qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf">-</a>
qh_fprintf(qhT *qh, fp, msgcode, format, list of args )
replaces qh_fprintf() in userprintf_r.c
notes:
only called from libqhull
same as fprintf() and RboxPoints.qh_fprintf_rbox()
fgets() is not trapped like fprintf()
Do not throw errors from here. Use qh_errexit;
*/
extern "C"
void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
using namespace orgQhull;
if(!qh->ISqhullQh){
qh_fprintf_stderr(10025, "Qhull error: qh_fprintf called from a Qhull instance without QhullQh defined\n");
qh_exit(10025);
}
QhullQh *qhullQh= static_cast<QhullQh *>(qh);
va_start(args, fmt);
if(msgcode<MSG_OUTPUT || fp == qh_FILEstderr){
if(msgcode>=MSG_ERROR && msgcode<MSG_WARNING){
if(qhullQh->qhull_status<MSG_ERROR || qhullQh->qhull_status>=MSG_WARNING){
qhullQh->qhull_status= msgcode;
}
}
char newMessage[MSG_MAXLEN];
// RoadError will add the message tag
vsnprintf(newMessage, sizeof(newMessage), fmt, args);
qhullQh->appendQhullMessage(newMessage);
va_end(args);
return;
}
if(qhullQh->output_stream && qhullQh->use_output_stream){
char newMessage[MSG_MAXLEN];
vsnprintf(newMessage, sizeof(newMessage), fmt, args);
*qhullQh->output_stream << newMessage;
va_end(args);
return;
}
// FIXUP QH11008: how do users trap messages and handle input? A callback?
char newMessage[MSG_MAXLEN];
vsnprintf(newMessage, sizeof(newMessage), fmt, args);
qhullQh->appendQhullMessage(newMessage);
va_end(args);
} /* qh_fprintf */

View File

@@ -0,0 +1,110 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.h#2 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLQH_H
#define QHULLQH_H
#include "libqhull_r/qhull_ra.h"
#include <string>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
/* setjmp should not be implemented with 'catch' */
#endif
//! Use QH_TRY_ or QH_TRY_NOTHROW_ to call a libqhull_r routine that may invoke qh_errexit()
//! QH_TRY_(qh){...} qh->NOerrexit=true;
//! No object creation -- longjmp() skips object destructors
//! To test for error when done -- qh->maybeThrowQhullMessage(QH_TRY_status);
//! Use the same compiler for QH_TRY_, libqhullcpp, and libqhull_r. setjmp() is not portable between compilers.
#define QH_TRY_ERROR 10071
#define QH_TRY_(qh) \
int QH_TRY_status; \
if(qh->NOerrexit){ \
qh->NOerrexit= False; \
QH_TRY_status= setjmp(qh->errexit); \
}else{ \
throw QhullError(QH_TRY_ERROR, "Cannot invoke QH_TRY_() from inside a QH_TRY_. Or missing 'qh->NOerrexit=true' after previously called QH_TRY_(qh){...}"); \
} \
if(!QH_TRY_status)
#define QH_TRY_NO_THROW_(qh) \
int QH_TRY_status; \
if(qh->NOerrexit){ \
qh->NOerrexit= False; \
QH_TRY_status= setjmp(qh->errexit); \
}else{ \
QH_TRY_status= QH_TRY_ERROR; \
} \
if(!QH_TRY_status)
namespace orgQhull {
#//!\name Defined here
//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
class QhullQh;
//! POD type equivalent to qhT. No virtual members
class QhullQh : public qhT {
#//!\name Constants
#//!\name Fields
private:
int qhull_status; //!< qh_ERRnone if valid
std::string qhull_message; //!< Returned messages from libqhull_r
std::ostream * error_stream; //!< overrides errorMessage, use appendQhullMessage()
std::ostream * output_stream; //!< send output to stream
double factor_epsilon; //!< Factor to increase ANGLEround and DISTround for hyperplane equality
bool use_output_stream; //!< True if using output_stream
friend void ::qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
static const double default_factor_epsilon; //!< Default factor_epsilon is 1.0, never updated
#//!\name Constructors
public:
QhullQh();
~QhullQh();
private:
//!disable copy constructor and assignment
QhullQh(const QhullQh &);
QhullQh & operator=(const QhullQh &);
public:
#//!\name GetSet
double factorEpsilon() const { return factor_epsilon; }
void setFactorEpsilon(double a) { factor_epsilon= a; }
void disableOutputStream() { use_output_stream= false; }
void enableOutputStream() { use_output_stream= true; }
#//!\name Messaging
void appendQhullMessage(const std::string &s);
void clearQhullMessage();
std::string qhullMessage() const;
bool hasOutputStream() const { return use_output_stream; }
bool hasQhullMessage() const;
void maybeThrowQhullMessage(int exitCode);
void maybeThrowQhullMessage(int exitCode, int noThrow) throw();
int qhullStatus() const;
void setErrorStream(std::ostream *os);
void setOutputStream(std::ostream *os);
#//!\name Methods
double angleEpsilon() const { return this->ANGLEround*factor_epsilon; } //!< Epsilon for hyperplane angle equality
void checkAndFreeQhullMemory();
double distanceEpsilon() const { return this->DISTround*factor_epsilon; } //!< Epsilon for distance to hyperplane
};//class QhullQh
}//namespace orgQhull
#endif // QHULLQH_H

View File

@@ -0,0 +1,124 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullRidge.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullSets.h"
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/Qhull.h"
#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
ridgeT QhullRidge::
s_empty_ridge= {0,0,0,0,0,
0,0};
#//!\name Constructors
QhullRidge::QhullRidge(const Qhull &q)
: qh_ridge(&s_empty_ridge)
, qh_qh(q.qh())
{
}//Default
QhullRidge::QhullRidge(const Qhull &q, ridgeT *r)
: qh_ridge(r ? r : &s_empty_ridge)
, qh_qh(q.qh())
{
}//ridgeT
#//!\name foreach
//! Return True if nextRidge3d
//! Simplicial facets may have incomplete ridgeSets
//! Does not use qh_errexit()
bool QhullRidge::
hasNextRidge3d(const QhullFacet &f) const
{
if(!qh_qh){
return false;
}
vertexT *v= 0;
// Does not call qh_errexit(), TRY_QHULL_ not needed
ridgeT *ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
return (ridge!=0);
}//hasNextRidge3d
//! Return next ridge and optional vertex for a 3d facet and ridge
//! Does not use qh_errexit()
QhullRidge QhullRidge::
nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const
{
vertexT *v= 0;
ridgeT *ridge= 0;
if(qh_qh){
// Does not call qh_errexit(), TRY_QHULL_ not needed
ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
if(!ridge){
throw QhullError(10030, "Qhull error nextRidge3d: missing next ridge for facet %d ridge %d. Does facet contain ridge?", f.id(), id());
}
}
if(nextVertex!=0){
*nextVertex= QhullVertex(qh_qh, v);
}
return QhullRidge(qh_qh, ridge);
}//nextRidge3d
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullRidge;
using orgQhull::QhullVertex;
ostream &
operator<<(ostream &os, const QhullRidge &r)
{
os << r.print("");
return os;
}//<< QhullRidge
//! Duplicate of qh_printridge [io_r.c]
ostream &
operator<<(ostream &os, const QhullRidge::PrintRidge &pr)
{
if(*pr.print_message){
os << pr.print_message << " ";
}else{
os << " - ";
}
QhullRidge r= *pr.ridge;
os << "r" << r.id();
if(r.getRidgeT()->tested){
os << " tested";
}
if(r.getRidgeT()->nonconvex){
os << " nonconvex";
}
os << endl;
os << r.vertices().print(" vertices:");
if(r.getRidgeT()->top && r.getRidgeT()->bottom){
os << " between f" << r.topFacet().id() << " and f" << r.bottomFacet().id() << endl;
}else if(r.getRidgeT()->top){
os << " top f" << r.topFacet().id() << endl;
}else if(r.getRidgeT()->bottom){
os << " bottom f" << r.bottomFacet().id() << endl;
}
return os;
}//<< PrintRidge

View File

@@ -0,0 +1,112 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullRidge.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLRIDGE_H
#define QHULLRIDGE_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/QhullVertexSet.h"
#include "libqhullcpp/QhullFacet.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Qhull;
class QhullVertex;
class QhullVertexSet;
class QhullFacet;
#//!\name Defined here
//! QhullRidge -- Qhull's ridge structure, ridgeT [libqhull.h], as a C++ class
class QhullRidge;
typedef QhullSet<QhullRidge> QhullRidgeSet;
typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
// see QhullSets.h for QhullRidgeSet and QhullRidgeSetIterator -- avoids circular references
/************************
a ridge is hull_dim-1 simplex between two neighboring facets. If the
facets are non-simplicial, there may be more than one ridge between
two facets. E.G. a 4-d hypercube has two triangles between each pair
of neighboring facets.
topological information:
vertices a set of vertices
top,bottom neighboring facets with orientation
geometric information:
tested True if ridge is clearly convex
nonconvex True if ridge is non-convex
*/
class QhullRidge {
#//!\name Defined here
public:
typedef ridgeT * base_type; // for QhullRidgeSet
#//!\name Fields
private:
ridgeT * qh_ridge; //!< Corresponding ridgeT, never 0
QhullQh * qh_qh; //!< QhullQh/qhT for ridgeT, may be 0
#//!\name Class objects
static ridgeT s_empty_ridge;
public:
#//!\name Constants
#//!\name Constructors
QhullRidge() : qh_ridge(&s_empty_ridge), qh_qh(0) {}
explicit QhullRidge(const Qhull &q);
QhullRidge(const Qhull &q, ridgeT *r);
explicit QhullRidge(QhullQh *qqh) : qh_ridge(&s_empty_ridge), qh_qh(qqh) {}
QhullRidge(QhullQh *qqh, ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge), qh_qh(qqh) {}
// Creates an alias. Does not copy QhullRidge. Needed for return by value and parameter passing
QhullRidge(const QhullRidge &other) : qh_ridge(other.qh_ridge), qh_qh(other.qh_qh) {}
// Creates an alias. Does not copy QhullRidge. Needed for vector<QhullRidge>
QhullRidge & operator=(const QhullRidge &other) { qh_ridge= other.qh_ridge; qh_qh= other.qh_qh; return *this; }
~QhullRidge() {}
#//!\name GetSet
QhullFacet bottomFacet() const { return QhullFacet(qh_qh, qh_ridge->bottom); }
int dimension() const { return ((qh_qh && qh_qh->hull_dim) ? qh_qh->hull_dim-1 : 0); }
ridgeT * getBaseT() const { return getRidgeT(); } //!< For QhullSet<QhullRidge>
ridgeT * getRidgeT() const { return qh_ridge; }
countT id() const { return qh_ridge->id; }
bool isValid() const { return (qh_qh && qh_ridge != &s_empty_ridge); }
bool operator==(const QhullRidge &other) const { return qh_ridge==other.qh_ridge; }
bool operator!=(const QhullRidge &other) const { return !operator==(other); }
QhullFacet otherFacet(const QhullFacet &f) const { return QhullFacet(qh_qh, (qh_ridge->top==f.getFacetT() ? qh_ridge->bottom : qh_ridge->top)); }
QhullFacet topFacet() const { return QhullFacet(qh_qh, qh_ridge->top); }
#//!\name foreach
bool hasNextRidge3d(const QhullFacet &f) const;
QhullRidge nextRidge3d(const QhullFacet &f) const { return nextRidge3d(f, 0); }
QhullRidge nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const;
QhullVertexSet vertices() const { return QhullVertexSet(qh_qh, qh_ridge->vertices); }
#//!\name IO
struct PrintRidge{
const QhullRidge *ridge;
const char * print_message; //!< non-null message
PrintRidge(const char *message, const QhullRidge &r) : ridge(&r), print_message(message) {}
};//PrintRidge
PrintRidge print(const char* message) const { return PrintRidge(message, *this); }
};//class QhullRidge
}//namespace orgQhull
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge &r);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge::PrintRidge &pr);
#endif // QHULLRIDGE_H

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullSet.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullSet -- Qhull's set structure, setT, as a C++ class
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullError.h"
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Class objects
setT QhullSetBase::
s_empty_set;
#//!\name Constructors
QhullSetBase::
QhullSetBase(const Qhull &q, setT *s)
: qh_set(s ? s : &s_empty_set)
, qh_qh(q.qh())
{
}
#//!\name Class methods
// Same code for qh_setsize [qset_r.c] and QhullSetBase::count [static]
countT QhullSetBase::
count(const setT *set)
{
countT size;
const setelemT *sizep;
if (!set){
return(0);
}
sizep= SETsizeaddr_(set);
if ((size= sizep->i)) {
size--;
if (size > set->maxsize) {
// FIXUP QH11022 How to add additional output to a error? -- qh_setprint(qhmem.ferr, "set: ", set);
throw QhullError(10032, "QhullSet internal error: current set size %d is greater than maximum size %d\n",
size, set->maxsize);
}
}else{
size= set->maxsize;
}
return size;
}//count
}//namespace orgQhull

View File

@@ -0,0 +1,462 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullSet.h#6 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QhullSet_H
#define QhullSet_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullQh.h"
#include <cstddef> // ptrdiff_t, size_t
#ifndef QHULL_NO_STL
#include <vector>
#endif
#ifdef QHULL_USES_QT
#include <QtCore/QList>
#endif
namespace orgQhull {
#//!\name Used here
class Qhull;
#//!\name Defined here
class QhullSetBase; //! Base class for QhullSet<T>
//! QhullSet<T> defined below
//! QhullSetIterator<T> defined below
//! \see QhullPointSet, QhullLinkedList<T>
//! QhullSetBase is a wrapper for Qhull's setT of void* pointers
//! \see libqhull_r/qset.h
class QhullSetBase {
private:
#//!\name Fields --
setT * qh_set;
QhullQh * qh_qh; //! Provides access to setT memory allocator
#//!\name Class objects
static setT s_empty_set; //! Used if setT* is NULL
public:
#//!\name Constructors
QhullSetBase(const Qhull &q, setT *s);
QhullSetBase(QhullQh *qqh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qqh) {}
//! Copy constructor copies the pointer but not the set. Needed for return by value and parameter passing.
QhullSetBase(const QhullSetBase &other) : qh_set(other.qh_set), qh_qh(other.qh_qh) {}
QhullSetBase & operator=(const QhullSetBase &other) { qh_set= other.qh_set; qh_qh= other.qh_qh; return *this; }
~QhullSetBase() {}
private:
//!disabled since memory allocation for QhullSet not defined
QhullSetBase() {}
public:
#//!\name GetSet
countT count() const { return QhullSetBase::count(qh_set); }
void defineAs(setT *s) { qh_set= s ? s : &s_empty_set; } //!< Not type-safe since setT may contain any type
void forceEmpty() { qh_set= &s_empty_set; }
setT * getSetT() const { return qh_set; }
bool isEmpty() const { return SETempty_(qh_set); }
QhullQh * qh() const { return qh_qh; }
setT ** referenceSetT() { return &qh_set; }
size_t size() const { return QhullSetBase::count(qh_set); }
#//!\name Element
protected:
void ** beginPointer() const { return &qh_set->e[0].p; }
void ** elementPointer(countT idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
//! Always points to 0
void ** endPointer() const { return qh_setendpointer(qh_set); }
#//!\name Class methods
public:
static countT count(const setT *set);
//s may be null
static bool isEmpty(const setT *s) { return SETempty_(s); }
};//QhullSetBase
//! QhullSet<T> -- A read-only wrapper to Qhull's collection class, setT.
//! QhullSet is similar to STL's <vector> and Qt's QVector
//! QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
//! T is a Qhull type that defines 'base_type' and getBaseT() (e.g., QhullFacet with base_type 'facetT *'
//! A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
//! QhullSetIterator is faster than STL-style iterator/const_iterator
//! Qhull's FOREACHelement_() [qset_r.h] maybe more efficient than QhullSet. It uses a NULL terminator instead of an end pointer. STL requires an end pointer.
//! Derived from QhullLinkedList.h and Qt/core/tools/qlist.h w/o QT_STRICT_ITERATORS
template <typename T>
class QhullSet : public QhullSetBase {
private:
#//!\name Fields -- see QhullSetBase
#//!\name Class objects
static setT s_empty_set; //! Workaround for no setT allocator. Used if setT* is NULL
public:
#//!\name Defined here
class iterator;
class const_iterator;
typedef typename QhullSet<T>::iterator Iterator;
typedef typename QhullSet<T>::const_iterator ConstIterator;
#//!\name Constructors
QhullSet<T>(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
QhullSet<T>(QhullQh *qqh, setT *s) : QhullSetBase(qqh, s) { }
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
//Copy constructor copies pointer but not contents. Needed for return by value.
QhullSet<T>(const QhullSet<T> &other) : QhullSetBase(other) {}
QhullSet<T> & operator=(const QhullSet<T> &other) { QhullSetBase::operator=(other); return *this; }
~QhullSet<T>() {}
private:
//!Disable default constructor. See QhullSetBase
QhullSet<T>();
public:
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<T> toStdVector() const;
#endif
#ifdef QHULL_USES_QT
QList<typename T> toQList() const;
#endif
#//!\name GetSet -- see QhullSetBase for count(), empty(), isEmpty(), size()
using QhullSetBase::count;
using QhullSetBase::isEmpty;
// operator== defined for QhullSets of the same type
bool operator==(const QhullSet<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
bool operator!=(const QhullSet<T> &other) const { return !operator==(other); }
#//!\name Element access
// Constructs T. Cannot return reference.
const T at(countT idx) const { return operator[](idx); }
// Constructs T. Cannot return reference.
const T back() const { return last(); }
T back() { return last(); }
//! end element is NULL
const typename T::base_type * constData() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
typename T::base_type * data() { return reinterpret_cast<typename T::base_type *>(beginPointer()); }
const typename T::base_type *data() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
typename T::base_type * endData() { return reinterpret_cast<typename T::base_type *>(endPointer()); }
const typename T::base_type * endData() const { return reinterpret_cast<const typename T::base_type *>(endPointer()); }
// Constructs T. Cannot return reference.
const T first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
T first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
// Constructs T. Cannot return reference.
const T front() const { return first(); }
T front() { return first(); }
// Constructs T. Cannot return reference.
const T last() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
T last() { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
// mid() not available. No setT constructor
// Constructs T. Cannot return reference.
const T operator[](countT idx) const { const typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
T operator[](countT idx) { typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
const T second() const { return operator[](1); }
T second() { return operator[](1); }
T value(countT idx) const;
T value(countT idx, const T &defaultValue) const;
#//!\name Read-write -- Not available, no setT constructor
#//!\name iterator
iterator begin() { return iterator(qh(), reinterpret_cast<typename T::base_type *>(beginPointer())); }
const_iterator begin() const { return const_iterator(qh(), data()); }
const_iterator constBegin() const { return const_iterator(qh(), data()); }
const_iterator constEnd() const { return const_iterator(qh(), endData()); }
iterator end() { return iterator(qh(), endData()); }
const_iterator end() const { return const_iterator(qh(), endData()); }
#//!\name Search
bool contains(const T &t) const;
countT count(const T &t) const;
countT indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
countT lastIndexOf(const T &t) const;
// before const_iterator for conversion with comparison operators
class iterator {
friend class const_iterator;
private:
typename T::base_type * i; // e.g., facetT**, first for debugger
QhullQh * qh_qh;
public:
typedef ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
iterator(QhullQh *qqh, typename T::base_type *p) : i(p), qh_qh(qqh) {}
iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
iterator & operator=(const iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
// Constructs T. Cannot return reference.
T operator*() const { return T(qh_qh, *i); }
//operator->() n/a, value-type
// Constructs T. Cannot return reference.
T operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
bool operator==(const iterator &o) const { return i == o.i; }
bool operator!=(const iterator &o) const { return !operator==(o); }
bool operator==(const const_iterator &o) const { return (i==reinterpret_cast<const iterator &>(o).i); }
bool operator!=(const const_iterator &o) const { return !operator==(o); }
//! Assumes same point set
countT operator-(const iterator &o) const { return (countT)(i-o.i); } //WARN64
bool operator>(const iterator &o) const { return i>o.i; }
bool operator<=(const iterator &o) const { return !operator>(o); }
bool operator<(const iterator &o) const { return i<o.i; }
bool operator>=(const iterator &o) const { return !operator<(o); }
bool operator>(const const_iterator &o) const { return (i > reinterpret_cast<const iterator &>(o).i); }
bool operator<=(const const_iterator &o) const { return !operator>(o); }
bool operator<(const const_iterator &o) const { return (i < reinterpret_cast<const iterator &>(o).i); }
bool operator>=(const const_iterator &o) const { return !operator<(o); }
//! No error checking
iterator & operator++() { ++i; return *this; }
iterator operator++(int) { iterator o= *this; ++i; return o; }
iterator & operator--() { --i; return *this; }
iterator operator--(int) { iterator o= *this; --i; return o; }
iterator operator+(countT j) const { return iterator(qh_qh, i+j); }
iterator operator-(countT j) const { return operator+(-j); }
iterator & operator+=(countT j) { i += j; return *this; }
iterator & operator-=(countT j) { i -= j; return *this; }
};//QhullPointSet::iterator
class const_iterator {
private:
const typename T::base_type * i; // e.g., const facetT**, first for debugger
QhullQh * qh_qh;
public:
typedef ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
const_iterator(QhullQh *qqh, const typename T::base_type * p) : i(p), qh_qh(qqh) {}
const_iterator(const const_iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
const_iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
const_iterator &operator=(const const_iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
// Constructs T. Cannot return reference. Retaining 'const T' return type for consistency with QList/QVector
const T operator*() const { return T(qh_qh, *i); }
const T operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
//operator->() n/a, value-type
bool operator==(const const_iterator &o) const { return i == o.i; }
bool operator!=(const const_iterator &o) const { return !operator==(o); }
//! Assumes same point set
countT operator-(const const_iterator &o) { return (countT)(i-o.i); } //WARN64
bool operator>(const const_iterator &o) const { return i>o.i; }
bool operator<=(const const_iterator &o) const { return !operator>(o); }
bool operator<(const const_iterator &o) const { return i<o.i; }
bool operator>=(const const_iterator &o) const { return !operator<(o); }
//!< No error checking
const_iterator &operator++() { ++i; return *this; }
const_iterator operator++(int) { const_iterator o= *this; ++i; return o; }
const_iterator &operator--() { --i; return *this; }
const_iterator operator--(int) { const_iterator o= *this; --i; return o; }
const_iterator operator+(int j) const { return const_iterator(qh_qh, i+j); }
const_iterator operator-(int j) const { return operator+(-j); }
const_iterator &operator+=(int j) { i += j; return *this; }
const_iterator &operator-=(int j) { i -= j; return *this; }
};//QhullPointSet::const_iterator
};//class QhullSet
//! Faster then interator/const_iterator due to T::base_type
template <typename T>
class QhullSetIterator {
#//!\name Subtypes
typedef typename QhullSet<T>::const_iterator const_iterator;
private:
#//!\name Fields
const typename T::base_type * i; // e.g., facetT**, first for debugger
const typename T::base_type * begin_i; // must be initialized after i
const typename T::base_type * end_i;
QhullQh * qh_qh;
public:
#//!\name Constructors
QhullSetIterator<T>(const QhullSet<T> &s) : i(s.data()), begin_i(i), end_i(s.endData()), qh_qh(s.qh()) {}
QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i), qh_qh(o.qh_qh) {}
QhullSetIterator<T> &operator=(const QhullSetIterator<T> &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; qh_qh= o.qh_qh; return *this; }
#//!\name ReadOnly
countT countRemaining() { return (countT)(end_i-i); } // WARN64
#//!\name Search
bool findNext(const T &t);
bool findPrevious(const T &t);
#//!\name Foreach
bool hasNext() const { return i != end_i; }
bool hasPrevious() const { return i != begin_i; }
T next() { return T(qh_qh, *i++); }
T peekNext() const { return T(qh_qh, *i); }
T peekPrevious() const { const typename T::base_type *p = i; return T(qh_qh, *--p); }
T previous() { return T(qh_qh, *--i); }
void toBack() { i = end_i; }
void toFront() { i = begin_i; }
};//class QhullSetIterator
#//!\name == Definitions =========================================
#//!\name Conversions
// See qt-qhull.cpp for QList conversion
#ifndef QHULL_NO_STL
template <typename T>
std::vector<T> QhullSet<T>::
toStdVector() const
{
typename QhullSet<T>::const_iterator i = begin();
typename QhullSet<T>::const_iterator e = end();
std::vector<T> vs;
while(i!=e){
vs.push_back(*i++);
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
template <typename T>
QList<T> QhullSet<T>::
toQList() const
{
QhullSet<T>::const_iterator i= begin();
QhullSet<T>::const_iterator e= end();
QList<T> vs;
while(i!=e){
vs.append(*i++);
}
return vs;
}//toQList
#endif
#//!\name Element
template <typename T>
T QhullSet<T>::
value(countT idx) const
{
// Avoid call to qh_setsize() and assert in elementPointer()
const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
return (idx>=0 && p<endData()) ? T(qh(), *p) : T(qh());
}//value
template <typename T>
T QhullSet<T>::
value(countT idx, const T &defaultValue) const
{
// Avoid call to qh_setsize() and assert in elementPointer()
const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
return (idx>=0 && p<endData() ? T(qh(), *p) : defaultValue);
}//value
#//!\name Search
template <typename T>
bool QhullSet<T>::
contains(const T &t) const
{
setT *s= getSetT();
void *p= t.getBaseT(); // contains() is not inline for better error reporting
int result= qh_setin(s, p);
return result!=0;
}//contains
template <typename T>
countT QhullSet<T>::
count(const T &t) const
{
countT n= 0;
const typename T::base_type *i= data();
const typename T::base_type *e= endData();
typename T::base_type p= t.getBaseT();
while(i<e){
if(*i==p){
n++;
}
i++;
}
return n;
}//count
template <typename T>
countT QhullSet<T>::
lastIndexOf(const T &t) const
{
const typename T::base_type *b= data();
const typename T::base_type *i= endData();
typename T::base_type p= t.getBaseT();
while(--i>=b){
if(*i==p){
break;
}
}
return (countT)(i-b); // WARN64
}//lastIndexOf
#//!\name QhullSetIterator
template <typename T>
bool QhullSetIterator<T>::
findNext(const T &t)
{
typename T::base_type p= t.getBaseT();
while(i!=end_i){
if(*(++i)==p){
return true;
}
}
return false;
}//findNext
template <typename T>
bool QhullSetIterator<T>::
findPrevious(const T &t)
{
typename T::base_type p= t.getBaseT();
while(i!=begin_i){
if(*(--i)==p){
return true;
}
}
return false;
}//findPrevious
}//namespace orgQhull
#//!\name == Global namespace =========================================
template <typename T>
std::ostream &
operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
{
const typename T::base_type *i= qs.data();
const typename T::base_type *e= qs.endData();
while(i!=e){
os << T(qs.qh(), *i++);
}
return os;
}//operator<<
#endif // QhullSet_H

View File

@@ -0,0 +1,27 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullSets.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLSETS_H
#define QHULLSETS_H
#include "libqhullcpp/QhullSet.h"
namespace orgQhull {
//See: QhullFacetSet.h
//See: QhullPointSet.h
//See: QhullVertexSet.h
// Avoid circular references between QhullFacet, QhullRidge, and QhullVertex
class QhullRidge;
typedef QhullSet<QhullRidge> QhullRidgeSet;
typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
}//namespace orgQhull
#endif // QHULLSETS_H

View File

@@ -0,0 +1,42 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullStat.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullStat -- Qhull's global data structure, statT, as a C++ class
#include "libqhullcpp/QhullStat.h"
#include "libqhullcpp/QhullError.h"
#include <sstream>
#include <iostream>
using std::cerr;
using std::string;
using std::vector;
using std::ostream;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Constructor, destructor, etc.
//! If qh_QHpointer==0, invoke with placement new on qh_stat;
QhullStat::
QhullStat()
{
}//QhullStat
QhullStat::
~QhullStat()
{
}//~QhullStat
}//namespace orgQhull

View File

@@ -0,0 +1,49 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullStat.h#2 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLSTAT_H
#define QHULLSTAT_H
#include "libqhull_r/qhull_ra.h"
#include <string>
#include <vector>
namespace orgQhull {
#//!\name defined here
//! QhullStat -- Qhull's statistics, qhstatT, as a C++ class
//! Statistics defined with zzdef_() control Qhull's behavior, summarize its result, and report precision problems.
class QhullStat;
class QhullStat : public qhstatT {
private:
#//!\name Fields (empty) -- POD type equivalent to qhstatT. No data or virtual members
public:
#//!\name Constants
#//!\name class methods
#//!\name constructor, assignment, destructor, invariant
QhullStat();
~QhullStat();
private:
//!disable copy constructor and assignment
QhullStat(const QhullStat &);
QhullStat & operator=(const QhullStat &);
public:
#//!\name Access
};//class QhullStat
}//namespace orgQhull
#endif // QHULLSTAT_H

View File

@@ -0,0 +1,112 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertex.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullFacetSet.h"
#include "libqhullcpp/QhullFacet.h"
#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
vertexT QhullVertex::
s_empty_vertex= {0,0,0,0,0,
0,0,0,0,0,
0};
#//!\name Constructors
QhullVertex::QhullVertex(const Qhull &q)
: qh_vertex(&s_empty_vertex)
, qh_qh(q.qh())
{
}//Default
QhullVertex::QhullVertex(const Qhull &q, vertexT *v)
: qh_vertex(v ? v : &s_empty_vertex)
, qh_qh(q.qh())
{
}//vertexT
#//!\name foreach
//! Return neighboring facets for a vertex
//! If neither merging nor Voronoi diagram, requires Qhull::defineVertexNeighborFacets() beforehand.
QhullFacetSet QhullVertex::
neighborFacets() const
{
if(!neighborFacetsDefined()){
throw QhullError(10034, "Qhull error: neighboring facets of vertex %d not defined. Please call Qhull::defineVertexNeighborFacets() beforehand.", id());
}
return QhullFacetSet(qh_qh, qh_vertex->neighbors);
}//neighborFacets
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using std::string;
using std::vector;
using orgQhull::QhullPoint;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetSet;
using orgQhull::QhullFacetSetIterator;
using orgQhull::QhullVertex;
//! Duplicate of qh_printvertex [io_r.c]
ostream &
operator<<(ostream &os, const QhullVertex::PrintVertex &pr)
{
QhullVertex v= *pr.vertex;
QhullPoint p= v.point();
if(*pr.print_message){
os << pr.print_message << " ";
}else{
os << "- ";
}
os << "p" << p.id() << " (v" << v.id() << "): ";
const realT *c= p.coordinates();
for(int k= p.dimension(); k--; ){
os << " " << *c++; // FIXUP QH11010 %5.2g
}
if(v.getVertexT()->deleted){
os << " deleted";
}
if(v.getVertexT()->delridge){
os << " ridgedeleted";
}
os << endl;
if(v.neighborFacetsDefined()){
QhullFacetSetIterator i= v.neighborFacets();
if(i.hasNext()){
os << " neighborFacets:";
countT count= 0;
while(i.hasNext()){
if(++count % 100 == 0){
os << endl << " ";
}
QhullFacet f= i.next();
os << " f" << f.id();
}
os << endl;
}
}
return os;
}//<< PrintVertex

View File

@@ -0,0 +1,104 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertex.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLVERTEX_H
#define QHULLVERTEX_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullLinkedList.h"
#include "libqhullcpp/QhullSet.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class QhullFacetSet;
#//!\name Defined here
//! QhullVertex -- Qhull's vertex structure, vertexT [libqhull_r.h], as a C++ class
class QhullVertex;
typedef QhullLinkedList<QhullVertex> QhullVertexList;
typedef QhullLinkedListIterator<QhullVertex> QhullVertexListIterator;
/*********************
topological information:
next,previous doubly-linked list of all vertices
neighborFacets set of adjacent facets (only if qh.VERTEXneighbors)
geometric information:
point array of DIM coordinates
*/
class QhullVertex {
#//!\name Defined here
public:
typedef vertexT * base_type; // for QhullVertexSet
private:
#//!\name Fields
vertexT * qh_vertex; //!< Corresponding vertexT, never 0
QhullQh * qh_qh; //!< QhullQh/qhT for vertexT, may be 0
#//!\name Class objects
static vertexT s_empty_vertex; // needed for shallow copy
public:
#//!\name Constants
#//!\name Constructors
QhullVertex() : qh_vertex(&s_empty_vertex), qh_qh(0) {}
explicit QhullVertex(const Qhull &q);
QhullVertex(const Qhull &q, vertexT *v);
explicit QhullVertex(QhullQh *qqh) : qh_vertex(&s_empty_vertex), qh_qh(qqh) {}
QhullVertex(QhullQh *qqh, vertexT *v) : qh_vertex(v ? v : &s_empty_vertex), qh_qh(qqh) {}
// Creates an alias. Does not copy QhullVertex. Needed for return by value and parameter passing
QhullVertex(const QhullVertex &other) : qh_vertex(other.qh_vertex), qh_qh(other.qh_qh) {}
// Creates an alias. Does not copy QhullVertex. Needed for vector<QhullVertex>
QhullVertex & operator=(const QhullVertex &other) { qh_vertex= other.qh_vertex; qh_qh= other.qh_qh; return *this; }
~QhullVertex() {}
#//!\name GetSet
int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
vertexT * getBaseT() const { return getVertexT(); } //!< For QhullSet<QhullVertex>
vertexT * getVertexT() const { return qh_vertex; }
countT id() const { return qh_vertex->id; }
bool isValid() const { return (qh_qh && qh_vertex != &s_empty_vertex); }
//! True if defineVertexNeighborFacets() already called. Auotomatically set for facet merging, Voronoi diagrams
bool neighborFacetsDefined() const { return qh_vertex->neighbors != 0; }
QhullVertex next() const { return QhullVertex(qh_qh, qh_vertex->next); }
bool operator==(const QhullVertex &other) const { return qh_vertex==other.qh_vertex; }
bool operator!=(const QhullVertex &other) const { return !operator==(other); }
QhullPoint point() const { return QhullPoint(qh_qh, qh_vertex->point); }
QhullVertex previous() const { return QhullVertex(qh_qh, qh_vertex->previous); }
QhullQh * qh() const { return qh_qh; }
#//!\name foreach
//See also QhullVertexList
QhullFacetSet neighborFacets() const;
#//!\name IO
struct PrintVertex{
const QhullVertex *vertex;
const char * print_message; //!< non-null message
PrintVertex(const char *message, const QhullVertex &v) : vertex(&v), print_message(message) {}
};//PrintVertex
PrintVertex print(const char *message) const { return PrintVertex(message, *this); }
};//class QhullVertex
}//namespace orgQhull
#//!\name GLobal
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex::PrintVertex &pr);
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex &v) { os << v.print(""); return os; }
#endif // QHULLVERTEX_H

View File

@@ -0,0 +1,161 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertexSet.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullVertexSet -- Qhull's linked Vertexs, as a C++ class
#include "libqhullcpp/QhullVertexSet.h"
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/Qhull.h"
using std::string;
using std::vector;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
/* setjmp should not be implemented with 'catch' */
#endif
namespace orgQhull {
QhullVertexSet::
QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets)
: QhullSet<QhullVertex>(q.qh(), 0)
, qhsettemp_defined(false)
{
QH_TRY_(q.qh()){ // no object creation -- destructors skipped on longjmp()
setT *vertices= qh_facetvertices(q.qh(), facetlist, facetset, allfacets);
defineAs(vertices);
qhsettemp_defined= true;
}
q.qh()->NOerrexit= true;
q.qh()->maybeThrowQhullMessage(QH_TRY_status);
}//QhullVertexSet facetlist facetset
//! Return tempory QhullVertexSet of vertices for a list and/or a set of facets
//! Sets qhsettemp_defined (disallows copy constructor and assignment to prevent double-free)
QhullVertexSet::
QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets)
: QhullSet<QhullVertex>(qqh, 0)
, qhsettemp_defined(false)
{
QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
setT *vertices= qh_facetvertices(qh(), facetlist, facetset, allfacets);
defineAs(vertices);
qhsettemp_defined= true;
}
qh()->NOerrexit= true;
qh()->maybeThrowQhullMessage(QH_TRY_status);
}//QhullVertexSet facetlist facetset
//! Copy constructor for argument passing and returning a result
//! Only copies a pointer to the set.
//! Throws an error if qhsettemp_defined, otherwise have a double-free
//!\todo Convert QhullVertexSet to a shared pointer with reference counting
QhullVertexSet::
QhullVertexSet(const QhullVertexSet &other)
: QhullSet<QhullVertex>(other)
, qhsettemp_defined(false)
{
if(other.qhsettemp_defined){
throw QhullError(10077, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet). Contains %d vertices", other.count());
}
}//copy constructor
//! Copy assignment only copies a pointer to the set.
//! Throws an error if qhsettemp_defined, otherwise have a double-free
QhullVertexSet & QhullVertexSet::
operator=(const QhullVertexSet &other)
{
QhullSet<QhullVertex>::operator=(other);
qhsettemp_defined= false;
if(other.qhsettemp_defined){
throw QhullError(10078, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet). Contains %d vertices", other.count());
}
return *this;
}//assignment
void QhullVertexSet::
freeQhSetTemp()
{
if(qhsettemp_defined){
qhsettemp_defined= false;
QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
qh_settempfree(qh(), referenceSetT()); // errors if not top of tempstack or if qhmem corrupted
}
qh()->NOerrexit= true;
qh()->maybeThrowQhullMessage(QH_TRY_status, QhullError::NOthrow);
}
}//freeQhSetTemp
QhullVertexSet::
~QhullVertexSet()
{
freeQhSetTemp();
}//~QhullVertexSet
//FIXUP -- Move conditional, QhullVertexSet code to QhullVertexSet.cpp
#ifndef QHULL_NO_STL
std::vector<QhullVertex> QhullVertexSet::
toStdVector() const
{
QhullSetIterator<QhullVertex> i(*this);
std::vector<QhullVertex> vs;
while(i.hasNext()){
QhullVertex v= i.next();
vs.push_back(v);
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullPoint;
using orgQhull::QhullVertex;
using orgQhull::QhullVertexSet;
using orgQhull::QhullVertexSetIterator;
//! Print Vertex identifiers to stream. Space prefix. From qh_printVertexheader [io_r.c]
ostream &
operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr)
{
os << pr.print_message;
for(QhullVertexSet::const_iterator i= pr.vertex_set->begin(); i!=pr.vertex_set->end(); ++i){
const QhullVertex v= *i;
os << " v" << v.id();
}
os << endl;
return os;
}//<<QhullVertexSet::PrintIdentifiers
//! Duplicate of printvertices [io_r.c]
ostream &
operator<<(ostream &os, const QhullVertexSet::PrintVertexSet &pr){
os << pr.print_message;
const QhullVertexSet *vs= pr.vertex_set;
QhullVertexSetIterator i= *vs;
while(i.hasNext()){
const QhullVertex v= i.next();
const QhullPoint p= v.point();
os << " p" << p.id() << "(v" << v.id() << ")";
}
os << endl;
return os;
}//<< PrintVertexSet

View File

@@ -0,0 +1,86 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertexSet.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLVERTEXSET_H
#define QHULLVERTEXSET_H
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullVertex.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
#//!\name Defined here
//! QhullVertexSet -- a set of Qhull Vertices, as a C++ class.
//! See Qhull
class QhullVertexSet;
typedef QhullSetIterator<QhullVertex> QhullVertexSetIterator;
class QhullVertexSet : public QhullSet<QhullVertex> {
private:
#//!\name Fields
bool qhsettemp_defined; //! Set was allocated with qh_settemp()
public:
#//!\name Constructor
QhullVertexSet(const Qhull &q, setT *s) : QhullSet<QhullVertex>(q, s), qhsettemp_defined(false) {}
QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets);
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
QhullVertexSet(QhullQh *qqh, setT *s) : QhullSet<QhullVertex>(qqh, s), qhsettemp_defined(false) {}
QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets);
//Copy constructor and assignment copies pointer but not contents. Throws error if qhsettemp_defined. Needed for return by value.
QhullVertexSet(const QhullVertexSet &other);
QhullVertexSet & operator=(const QhullVertexSet &other);
~QhullVertexSet();
private: //!Default constructor disabled. Will implement allocation later
QhullVertexSet();
public:
#//!\name Destructor
void freeQhSetTemp();
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<QhullVertex> toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullVertex> toQList() const;
#endif //QHULL_USES_QT
#//!\name IO
struct PrintVertexSet{
const QhullVertexSet *vertex_set;
const char * print_message; //!< non-null message
PrintVertexSet(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
};//PrintVertexSet
const PrintVertexSet print(const char *message) const { return PrintVertexSet(message, this); }
struct PrintIdentifiers{
const QhullVertexSet *vertex_set;
const char * print_message; //!< non-null message
PrintIdentifiers(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
};//PrintIdentifiers
PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
};//class QhullVertexSet
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintVertexSet &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintIdentifiers &p);
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet &vs) { os << vs.print(""); return os; }
#endif // QHULLVERTEXSET_H

View File

@@ -0,0 +1,224 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/RboxPoints.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/RboxPoints.h"
#include "libqhullcpp/QhullError.h"
#include <iostream>
using std::cerr;
using std::endl;
using std::istream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::vector;
using std::ws;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//! RboxPoints -- generate random PointCoordinates for qhull (rbox)
#//!\name Constructors
RboxPoints::
RboxPoints()
: PointCoordinates("rbox")
, rbox_new_count(0)
, rbox_status(qh_ERRnone)
, rbox_message()
{
allocateQhullQh();
}
//! Allocate and generate points according to rboxCommand
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
//! Same as appendPoints()
RboxPoints::
RboxPoints(const char *rboxCommand)
: PointCoordinates("rbox")
, rbox_new_count(0)
, rbox_status(qh_ERRnone)
, rbox_message()
{
allocateQhullQh();
// rbox arguments added to comment() via qh_rboxpoints > qh_fprintf_rbox
appendPoints(rboxCommand);
}
RboxPoints::
~RboxPoints()
{
delete qh();
resetQhullQh(0);
}
// RboxPoints and qh_rboxpoints has several fields in qhT (rbox_errexit..cpp_object)
// It shares last_random with qh_rand and qh_srand
// The other fields are unused
void RboxPoints::
allocateQhullQh()
{
QHULL_LIB_CHECK /* Check for compatible library */
resetQhullQh(new QhullQh);
}//allocateQhullQh
#//!\name Messaging
void RboxPoints::
clearRboxMessage()
{
rbox_status= qh_ERRnone;
rbox_message.clear();
}//clearRboxMessage
std::string RboxPoints::
rboxMessage() const
{
if(rbox_status!=qh_ERRnone){
return rbox_message;
}
if(isEmpty()){
return "rbox warning: no points generated\n";
}
return "rbox: OK\n";
}//rboxMessage
int RboxPoints::
rboxStatus() const
{
return rbox_status;
}
bool RboxPoints::
hasRboxMessage() const
{
return (rbox_status!=qh_ERRnone);
}
#//!\name Methods
//! Appends points as defined by rboxCommand
//! Appends rboxCommand to comment
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
void RboxPoints::
appendPoints(const char *rboxCommand)
{
string s("rbox ");
s += rboxCommand;
char *command= const_cast<char*>(s.c_str());
if(qh()->cpp_object){
throw QhullError(10001, "Qhull error: conflicting user of cpp_object for RboxPoints::appendPoints() or corrupted qh_qh");
}
if(extraCoordinatesCount()!=0){
throw QhullError(10067, "Qhull error: Extra coordinates (%d) prior to calling RboxPoints::appendPoints. Was %s", extraCoordinatesCount(), 0, 0.0, comment().c_str());
}
countT previousCount= count();
qh()->cpp_object= this; // for qh_fprintf_rbox()
int status= qh_rboxpoints(qh(), command);
qh()->cpp_object= 0;
if(rbox_status==qh_ERRnone){
rbox_status= status;
}
if(rbox_status!=qh_ERRnone){
throw QhullError(rbox_status, rbox_message);
}
if(extraCoordinatesCount()!=0){
throw QhullError(10002, "Qhull error: extra coordinates (%d) for PointCoordinates (%x)", extraCoordinatesCount(), 0, 0.0, coordinates());
}
if(previousCount+newCount()!=count()){
throw QhullError(10068, "Qhull error: rbox specified %d points but got %d points for command '%s'", newCount(), count()-previousCount, 0.0, comment().c_str());
}
}//appendPoints
}//namespace orgQhull
#//!\name Global functions
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
fp is ignored (replaces qh_fprintf_rbox() in userprintf_rbox.c)
cpp_object == RboxPoints
notes:
only called from qh_rboxpoints()
same as fprintf() and Qhull.qh_fprintf()
fgets() is not trapped like fprintf()
Do not throw errors from here. Use qh_errexit_rbox;
A similar technique can be used for qh_fprintf to capture all of its output
*/
extern "C"
void qh_fprintf_rbox(qhT *qh, FILE*, int msgcode, const char *fmt, ... ) {
va_list args;
using namespace orgQhull;
if(!qh->cpp_object){
qh_errexit_rbox(qh, 10072);
}
RboxPoints *out= reinterpret_cast<RboxPoints *>(qh->cpp_object);
va_start(args, fmt);
if(msgcode<MSG_OUTPUT){
char newMessage[MSG_MAXLEN];
// RoadError provides the message tag
vsnprintf(newMessage, sizeof(newMessage), fmt, args);
out->rbox_message += newMessage;
if(out->rbox_status<MSG_ERROR || out->rbox_status>=MSG_STDERR){
out->rbox_status= msgcode;
}
va_end(args);
return;
}
switch(msgcode){
case 9391:
case 9392:
out->rbox_message += "RboxPoints error: options 'h', 'n' not supported.\n";
qh_errexit_rbox(qh, 10010);
/* never returns */
case 9393: // FIXUP QH11026 countT vs. int
{
int dimension= va_arg(args, int);
string command(va_arg(args, char*));
countT count= va_arg(args, countT);
out->setDimension(dimension);
out->appendComment(" \"");
out->appendComment(command.substr(command.find(' ')+1));
out->appendComment("\"");
out->setNewCount(count);
out->reservePoints();
}
break;
case 9407:
*out << va_arg(args, int);
// fall through
case 9405:
*out << va_arg(args, int);
// fall through
case 9403:
*out << va_arg(args, int);
break;
case 9408:
*out << va_arg(args, double);
// fall through
case 9406:
*out << va_arg(args, double);
// fall through
case 9404:
*out << va_arg(args, double);
break;
}
va_end(args);
} /* qh_fprintf_rbox */

View File

@@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/RboxPoints.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef RBOXPOINTS_H
#define RBOXPOINTS_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/PointCoordinates.h"
#include <stdarg.h>
#include <string>
#include <vector>
#include <istream>
#include <ostream>
#include <sstream>
namespace orgQhull {
#//!\name Defined here
//! RboxPoints -- generate random PointCoordinates for Qhull
class RboxPoints;
class RboxPoints : public PointCoordinates {
private:
#//!\name Fields and friends
//! PointCoordinates.qh() is owned by RboxPoints
countT rbox_new_count; //! Number of points for PointCoordinates
int rbox_status; //! error status from rboxpoints. qh_ERRnone if none.
std::string rbox_message; //! stderr from rboxpoints
// '::' is required for friend references
friend void ::qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
public:
#//!\name Construct
RboxPoints();
explicit RboxPoints(const char *rboxCommand);
~RboxPoints();
private: // Disable copy constructor and assignment. RboxPoints owns QhullQh.
RboxPoints(const RboxPoints &);
RboxPoints &operator=(const RboxPoints &);
private:
void allocateQhullQh();
public:
#//!\name GetSet
void clearRboxMessage();
countT newCount() const { return rbox_new_count; }
std::string rboxMessage() const;
int rboxStatus() const;
bool hasRboxMessage() const;
void setNewCount(countT pointCount) { QHULL_ASSERT(pointCount>=0); rbox_new_count= pointCount; }
#//!\name Modify
void appendPoints(const char* rboxCommand);
using PointCoordinates::appendPoints;
void reservePoints() { reserveCoordinates((count()+newCount())*dimension()); }
};//class RboxPoints
}//namespace orgQhull
#endif // RBOXPOINTS_H

View File

@@ -0,0 +1,158 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/RoadError.cpp#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
#//! Do not throw RoadError's from destructors. Use e.logError() instead.
#include "libqhullcpp/RoadError.h"
#include <string>
#include <sstream>
#include <iostream>
using std::cerr;
using std::cout;
using std::string;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Class fields
//! Identifies error messages from Qhull and Road for web searches.
//! See QhullError.h#QHULLlastError and user.h#MSG_ERROR
const char * RoadError::
ROADtag= "QH";
std::ostringstream RoadError::
global_log;
#//!\name Constructor
RoadError::
RoadError()
: error_code(0)
, log_event()
, error_message()
{ }
RoadError::
RoadError(const RoadError &other)
: error_code(other.error_code)
, log_event(other.log_event)
, error_message(other.error_message)
{
}//copy construct
RoadError::
RoadError(int code, const std::string &message)
: error_code(code)
, log_event(message.c_str())
, error_message(log_event.toString(ROADtag, error_code))
{
log_event.cstr_1= error_message.c_str(); // overwrites initial value
}
RoadError::
RoadError(int code, const char *fmt)
: error_code(code)
, log_event(fmt)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d)
: error_code(code)
, log_event(fmt, d)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2)
: error_code(code)
, log_event(fmt, d, d2)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2, float f)
: error_code(code)
, log_event(fmt, d, d2, f)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2, float f, const char *s)
: error_code(code)
, log_event(fmt, d, d2, f, s)
, error_message(log_event.toString(ROADtag, code)) // char * may go out of scope
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2, float f, const void *x)
: error_code(code)
, log_event(fmt, d, d2, f, x)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2, float f, int i)
: error_code(code)
, log_event(fmt, d, d2, f, i)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2, float f, long long i)
: error_code(code)
, log_event(fmt, d, d2, f, i)
, error_message()
{ }
RoadError::
RoadError(int code, const char *fmt, int d, int d2, float f, double e)
: error_code(code)
, log_event(fmt, d, d2, f, e)
, error_message()
{ }
RoadError & RoadError::
operator=(const RoadError &other)
{
error_code= other.error_code;
error_message= other.error_message;
log_event= other.log_event;
return *this;
}//operator=
#//!\name Virtual
const char * RoadError::
what() const throw()
{
if(error_message.empty()){
error_message= log_event.toString(ROADtag, error_code);
}
return error_message.c_str();
}//what
#//!\name Updates
//! Log error instead of throwing it.
//! Not reentrant, so avoid using it if possible
//!\todo Redesign with a thread-local stream or a reentrant ostringstream
void RoadError::
logErrorLastResort() const
{
global_log << what() << endl;
}//logError
}//namespace orgQhull

View File

@@ -0,0 +1,88 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/RoadError.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef ROADERROR_H
#define ROADERROR_H
#include "libqhull_r/user_r.h" /* for QHULL_CRTDBG */
#include "libqhullcpp/RoadLogEvent.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
using std::endl;
namespace orgQhull {
#//!\name Defined here
//! RoadError -- Report and log errors
//! See discussion in Saylan, G., "Practical C++ error handling in hybrid environments," Dr. Dobb's Journal, p. 50-55, March 2007.
//! He uses an auto_ptr to track a stringstream. It constructs a string on the fly. RoadError uses the copy constructor to transform RoadLogEvent into a string
class RoadError;
class RoadError : public std::exception {
private:
#//!\name Fields
int error_code; //! Non-zero code (not logged), maybe returned as program status
RoadLogEvent log_event; //! Format string w/ arguments
mutable std::string error_message; //! Formated error message. Must be after log_event.
#//!\name Class fields
static const char * ROADtag;
static std::ostringstream global_log; //!< May be replaced with any ostream object
//!< Not reentrant -- only used by RoadError::logErrorLastResort()
public:
#//!\name Constants
#//!\name Constructors
RoadError();
RoadError(const RoadError &other); //! Called on throw, generates error_message
RoadError(int code, const std::string &message);
RoadError(int code, const char *fmt);
RoadError(int code, const char *fmt, int d);
RoadError(int code, const char *fmt, int d, int d2);
RoadError(int code, const char *fmt, int d, int d2, float f);
RoadError(int code, const char *fmt, int d, int d2, float f, const char *s);
RoadError(int code, const char *fmt, int d, int d2, float f, const void *x);
RoadError(int code, const char *fmt, int d, int d2, float f, int i);
RoadError(int code, const char *fmt, int d, int d2, float f, long long i);
RoadError(int code, const char *fmt, int d, int d2, float f, double e);
RoadError & operator=(const RoadError &other);
~RoadError() throw() {};
#//!\name Class methods
static void clearGlobalLog() { global_log.seekp(0); }
static bool emptyGlobalLog() { return global_log.tellp()<=0; }
static const char *stringGlobalLog() { return global_log.str().c_str(); }
#//!\name Virtual
virtual const char *what() const throw();
#//!\name GetSet
bool isValid() const { return log_event.isValid(); }
int errorCode() const { return error_code; };
// FIXUP QH11021 should RoadError provide errorMessage(). Currently what()
RoadLogEvent roadLogEvent() const { return log_event; };
#//!\name Update
void logErrorLastResort() const;
};//class RoadError
}//namespace orgQhull
#//!\name Global
inline std::ostream & operator<<(std::ostream &os, const orgQhull::RoadError &e) { return os << e.what(); }
#endif // ROADERROR_H

View File

@@ -0,0 +1,122 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/RoadLogEvent.cpp#3 $$Change: 2066 $
** $Date: 2016/01/18 $$Author: bbarber $
**
****************************************************************************/
#//! RoadLogEvent -- All exceptions thrown by Qhull are RoadErrors
#include "libqhullcpp/RoadLogEvent.h"
#include <string>
#include <sstream>
#include <iostream>
using std::cout;
using std::endl;
using std::ostringstream;
using std::string;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//!\name Conversion
string RoadLogEvent::
toString(const char *tag, int code) const
{
ostringstream os;
if(tag && code){
os << tag << code;
if(format_string){
os << " ";
}
}
if(!format_string){
return os.str();
}
const char *s= format_string;
int dCount= 0; // Count of %d
int fCount= 0; // Count of %f
char extraCode= '\0';
while(*s){
if(*s!='%'){
os << *s++;
}else{
char c= *++s;
s++;
switch(c){
case 'd':
if(++dCount>2){
os << " ERROR_three_%d_in_format ";
}else if(dCount==2){
os << int_2;
}else{
os << int_1;
}
break;
case 'e':
if(firstExtraCode(os, c, &extraCode)){
os << double_1;
}
break;
case 'f':
if(++fCount>1){
os << " ERROR_two_%f_in_format ";
}else{
os << float_1;
}
break;
case 'i':
if(firstExtraCode(os, c, &extraCode)){
os << int64_1;
}
break;
case 's':
if(firstExtraCode(os, c, &extraCode)){
os << cstr_1;
}
break;
case 'u':
if(firstExtraCode(os, c, &extraCode)){
os << "0x" << std::hex << int64_1 << std::dec;
}
break;
case 'x':
if(firstExtraCode(os, c, &extraCode)){
os << void_1;
}
break;
case '%':
os << c;
break;
default:
os << " ERROR_%" << c << "_not_defined_in_format";
break;
}
}
}
if(s[-1]!='\n'){
os << endl;
}
return os.str();
}//toString
#//!\name Class helpers (static)
//! True if this char is the first extra code
bool RoadLogEvent::
firstExtraCode(std::ostream &os, char c, char *extraCode){
if(*extraCode){
os << " ERROR_%" << *extraCode << "_and_%" << c << "_in_format ";
return false;
}
*extraCode= c;
return true;
}//firstExtraCode
}//namespace orgQhull

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/RoadLogEvent.h#1 $$Change: 1981 $
** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
**
****************************************************************************/
#ifndef ROADLOGEVENT_H
#define ROADLOGEVENT_H
#include <ostream>
#include <stdexcept>
#include <string>
namespace orgQhull {
#//!\name Defined here
//! RoadLogEvent -- Record an event for the RoadLog
struct RoadLogEvent;
struct RoadLogEvent {
public:
#//!\name Fields
const char * format_string; //! Format string (a literal with format codes, for logging)
int int_1; //! Integer argument (%d, for logging)
int int_2; //! Integer argument (%d, for logging)
float float_1; //! Float argument (%f, for logging)
union { //! One additional argument (for logging)
const char *cstr_1; //! Cstr argument (%s) -- type checked at construct-time
const void *void_1; //! Void* argument (%x) -- Use upper-case codes for object types
long long int64_1; //! signed int64 (%i). Ambiguous if unsigned is also defined.
double double_1; //! Double argument (%e)
};
#//!\name Constants
#//!\name Constructors
RoadLogEvent() : format_string(0), int_1(0), int_2(0), float_1(0), int64_1(0) {};
explicit RoadLogEvent(const char *fmt) : format_string(fmt), int_1(0), int_2(0), float_1(0), int64_1(0) {};
RoadLogEvent(const char *fmt, int d) : format_string(fmt), int_1(d), int_2(0), float_1(0), int64_1(0) {};
RoadLogEvent(const char *fmt, int d, int d2) : format_string(fmt), int_1(d), int_2(d2), float_1(0), int64_1(0) {};
RoadLogEvent(const char *fmt, int d, int d2, float f) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(0) {};
RoadLogEvent(const char *fmt, int d, int d2, float f, const char *s) : format_string(fmt), int_1(d), int_2(d2), float_1(f), cstr_1(s) {};
RoadLogEvent(const char *fmt, int d, int d2, float f, const void *x) : format_string(fmt), int_1(d), int_2(d2), float_1(f), void_1(x) {};
RoadLogEvent(const char *fmt, int d, int d2, float f, int i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {};
RoadLogEvent(const char *fmt, int d, int d2, float f, long long i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {};
RoadLogEvent(const char *fmt, int d, int d2, float f, double g) : format_string(fmt), int_1(d), int_2(d2), float_1(f), double_1(g) {};
~RoadLogEvent() {};
//! Default copy constructor and assignment
#//!\name GetSet
bool isValid() const { return format_string!=0; }
int int1() const { return int_1; };
int int2() const { return int_2; };
float float1() const { return float_1; };
const char * format() const { return format_string; };
const char * cstr1() const { return cstr_1; };
const void * void1() const { return void_1; };
long long int64() const { return int64_1; };
double double1() const { return double_1; };
#//!\name Conversion
std::string toString(const char* tag, int code) const;
private:
#//!\name Class helpers
static bool firstExtraCode(std::ostream &os, char c, char *extraCode);
};//class RoadLogEvent
}//namespace orgQhull
#endif // ROADLOGEVENT_H

View File

@@ -0,0 +1,67 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/functionObjects.h#1 $$Change: 1981 $
** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHFUNCTIONOBJECTS_H
#define QHFUNCTIONOBJECTS_H
#include <stdlib.h>
#include <math.h>
namespace orgQhull {
#//!\name Defined here
//! Sum of absolute values of the elements in a container
class AbsoluteSumOf;
//! Sum of the elements in a container
class SumOf;
//! Sum of squares of the elements in a container
class SumSquaresOf;
#//!\name Class
//! Absolute sum of the elements in a container
class AbsoluteSumOf
{
private:
double sum;
public:
inline AbsoluteSumOf() : sum(0.0) {}
inline void operator()(double v) { sum += fabs(v); }
inline operator double() { return sum; }
};//AbsoluteSumOf
//! Sum of the elements in a container
class SumOf
{
private:
double sum;
public:
inline SumOf() : sum(0.0) {}
inline void operator()(double v) { sum += v; }
inline operator double() { return sum; }
};//SumOf
//! Sum of squares of the elements in a container
class SumSquaresOf
{
private:
double sum;
public:
inline SumSquaresOf() : sum(0.0) {}
inline void operator()(double v) { sum += v*v; }
inline operator double() { return sum; }
};//SumSquaresOf
}//orgQhull
#endif //QHFUNCTIONOBJECTS_H

View File

@@ -0,0 +1,71 @@
# -------------------------------------------------
# libqhullcpp.pro -- Qt project for Qhull cpp shared library
#
# It uses reentrant Qhull
# -------------------------------------------------
include(../qhull-warn.pri)
DESTDIR = ../../lib
TEMPLATE = lib
# Do not create libqhullcpp as a shared library. Qhull C++ classes may change layout and size.
CONFIG += staticlib warn_on
CONFIG -= qt rtti
build_pass:CONFIG(debug, debug|release):{
TARGET = qhullcpp_d
OBJECTS_DIR = Debug
}else:build_pass:CONFIG(release, debug|release):{
TARGET = qhullcpp
OBJECTS_DIR = Release
}
MOC_DIR = moc
INCLUDEPATH += ../../src
INCLUDEPATH += $$PWD # for MOC_DIR
CONFIG += qhull_warn_shadow qhull_warn_conversion
SOURCES += ../libqhullcpp/Coordinates.cpp
SOURCES += ../libqhullcpp/PointCoordinates.cpp
SOURCES += ../libqhullcpp/Qhull.cpp
SOURCES += ../libqhullcpp/QhullFacet.cpp
SOURCES += ../libqhullcpp/QhullFacetList.cpp
SOURCES += ../libqhullcpp/QhullFacetSet.cpp
SOURCES += ../libqhullcpp/QhullHyperplane.cpp
SOURCES += ../libqhullcpp/QhullPoint.cpp
SOURCES += ../libqhullcpp/QhullPoints.cpp
SOURCES += ../libqhullcpp/QhullPointSet.cpp
SOURCES += ../libqhullcpp/QhullQh.cpp
SOURCES += ../libqhullcpp/QhullRidge.cpp
SOURCES += ../libqhullcpp/QhullSet.cpp
SOURCES += ../libqhullcpp/QhullStat.cpp
SOURCES += ../libqhullcpp/QhullVertex.cpp
SOURCES += ../libqhullcpp/QhullVertexSet.cpp
SOURCES += ../libqhullcpp/RboxPoints.cpp
SOURCES += ../libqhullcpp/RoadError.cpp
SOURCES += ../libqhullcpp/RoadLogEvent.cpp
HEADERS += ../libqhullcpp/Coordinates.h
HEADERS += ../libqhullcpp/functionObjects.h
HEADERS += ../libqhullcpp/PointCoordinates.h
HEADERS += ../libqhullcpp/Qhull.h
HEADERS += ../libqhullcpp/QhullError.h
HEADERS += ../libqhullcpp/QhullFacet.h
HEADERS += ../libqhullcpp/QhullFacetList.h
HEADERS += ../libqhullcpp/QhullFacetSet.h
HEADERS += ../libqhullcpp/QhullHyperplane.h
HEADERS += ../libqhullcpp/QhullIterator.h
HEADERS += ../libqhullcpp/QhullLinkedList.h
HEADERS += ../libqhullcpp/QhullPoint.h
HEADERS += ../libqhullcpp/QhullPoints.h
HEADERS += ../libqhullcpp/QhullPointSet.h
HEADERS += ../libqhullcpp/QhullQh.h
HEADERS += ../libqhullcpp/QhullRidge.h
HEADERS += ../libqhullcpp/QhullSet.h
HEADERS += ../libqhullcpp/QhullSets.h
HEADERS += ../libqhullcpp/QhullStat.h
HEADERS += ../libqhullcpp/QhullVertex.h
HEADERS += ../libqhullcpp/QhullVertexSet.h
HEADERS += ../libqhullcpp/RboxPoints.h
HEADERS += ../libqhullcpp/RoadError.h
HEADERS += ../libqhullcpp/RoadLogEvent.h

View File

@@ -0,0 +1,130 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/qt-qhull.cpp#1 $$Change: 1981 $
** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
**
****************************************************************************/
#include <QList>
#include "qhulltest/RoadTest.h"
#ifndef QHULL_USES_QT
#define QHULL_USES_QT 1
#endif
#include "Coordinates.h"
#include "QhullFacetList.h"
#include "QhullFacetSet.h"
#include "QhullHyperplane.h"
#include "QhullPoint.h"
#include "QhullPoints.h"
#include "QhullPointSet.h"
#include "QhullVertex.h"
#include "QhullVertexSet.h"
namespace orgQhull {
#//!\name Conversions
QList<coordT> Coordinates::
toQList() const
{
CoordinatesIterator i(*this);
QList<coordT> cs;
while(i.hasNext()){
cs.append(i.next());
}
return cs;
}//toQList
QList<QhullFacet> QhullFacetList::
toQList() const
{
QhullLinkedListIterator<QhullFacet> i(*this);
QList<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.append(f);
}
}
return vs;
}//toQList
//! Same as PrintVertices
QList<QhullVertex> QhullFacetList::
vertices_toQList() const
{
QList<QhullVertex> vs;
QhullVertexSet qvs(qh(), first().getFacetT(), NULL, isSelectAll());
for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
vs.push_back(*i);
}
return vs;
}//vertices_toQList
QList<QhullFacet> QhullFacetSet::
toQList() const
{
QhullSetIterator<QhullFacet> i(*this);
QList<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.append(f);
}
}
return vs;
}//toQList
#ifdef QHULL_USES_QT
QList<coordT> QhullHyperplane::
toQList() const
{
QhullHyperplaneIterator i(*this);
QList<coordT> fs;
while(i.hasNext()){
fs.append(i.next());
}
fs.append(hyperplane_offset);
return fs;
}//toQList
#endif //QHULL_USES_QT
QList<coordT> QhullPoint::
toQList() const
{
QhullPointIterator i(*this);
QList<coordT> vs;
while(i.hasNext()){
vs.append(i.next());
}
return vs;
}//toQList
QList<QhullPoint> QhullPoints::
toQList() const
{
QhullPointsIterator i(*this);
QList<QhullPoint> vs;
while(i.hasNext()){
vs.append(i.next());
}
return vs;
}//toQList
/******
QList<QhullPoint> QhullPointSet::
toQList() const
{
QhullPointSetIterator i(*this);
QList<QhullPoint> vs;
while(i.hasNext()){
vs.append(i.next());
}
return vs;
}//toQList
*/
}//orgQhull

View File

@@ -0,0 +1,93 @@
/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
usermem_r-cpp.cpp
Redefine qh_exit() as 'throw std::runtime_error("QH10003 ...")'
This file is not included in the Qhull builds.
qhull_r calls qh_exit() when qh_errexit() is not available. For example,
it calls qh_exit() if you linked the wrong qhull library.
The C++ interface avoids most of the calls to qh_exit().
If needed, include usermem_r-cpp.o before libqhullstatic_r.a. You may need to
override duplicate symbol errors (e.g. /FORCE:MULTIPLE for DevStudio). It
may produce a warning about throwing an error from C code.
*/
extern "C" {
void qh_exit(int exitcode);
}
#include <stdexcept>
#include <stdlib.h>
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_exit">-</a>
qh_exit( exitcode )
exit program
notes:
same as exit()
*/
void qh_exit(int exitcode) {
exitcode= exitcode;
throw std::runtime_error("QH10003 Qhull error. See stderr or errfile.");
} /* exit */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_stderr">-</a>
qh_fprintf_stderr( msgcode, format, list of args )
fprintf to stderr with msgcode (non-zero)
notes:
qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
It is typically followed by qh_errexit().
Redefine this function to avoid using stderr
Use qh_fprintf [userprintf_r.c] for normal printing
*/
void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
va_list args;
va_start(args, fmt);
if(msgcode)
fprintf(stderr, "QH%.4d ", msgcode);
vfprintf(stderr, fmt, args);
va_end(args);
} /* fprintf_stderr */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_free">-</a>
qh_free(qhT *qh, mem )
free memory
notes:
same as free()
No calls to qh_errexit()
*/
void qh_free(void *mem) {
free(mem);
} /* free */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_malloc">-</a>
qh_malloc( mem )
allocate memory
notes:
same as malloc()
*/
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */