diff --git a/cpp/Qhull.cpp b/cpp/Qhull.cpp index 39318292ff741480daaf6c0074c2853f0919640c..de43d7ef95e665410b699282f6faae18d7d9a844 100644 --- a/cpp/Qhull.cpp +++ b/cpp/Qhull.cpp @@ -292,6 +292,23 @@ volume(){ }//volume #//ForEach + +//! Define QhullVertex::neighborFacets(). +//! Automatically called if merging facets or computing the Voronoi diagram. +//! Noop if called multiple times. +void Qhull:: +defineVertexNeighborFacets(){ + checkIfQhullInitialized(); + UsingLibQhull q(this); + if(!qh hasAreaVolume){ + int exitCode = setjmp(qh errexit); + if(!exitCode){ // no object creation -- destructors skipped on longjmp() + qh_vertexneighbors(); + } + maybeThrowQhullMessage(exitCode); + } +}//defineVertexNeighborFacets + QhullFacetList Qhull:: facetList() const{ return QhullFacetList(beginFacet(), endFacet()); @@ -309,6 +326,7 @@ otherPoints() const return QhullPointSet(hullDimension(), qhull_qh->other_points); }//otherPoints +//! Return vertices of the convex hull. QhullVertexList Qhull:: vertexList() const{ return QhullVertexList(beginVertex(), endVertex()); diff --git a/cpp/Qhull.h b/cpp/Qhull.h index b3b9768e1b5b5215cc1e93a2cab6515366189ed0..aa63f27826a312e84275d43258c60f962a87aa24 100644 --- a/cpp/Qhull.h +++ b/cpp/Qhull.h @@ -116,6 +116,7 @@ public: #//ForEach QhullFacet beginFacet() const { return QhullFacet(qhull_qh->facet_list); } QhullVertex beginVertex() const { return QhullVertex(qhull_qh->vertex_list); } + void defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram QhullFacet endFacet() const { return QhullFacet(qhull_qh->facet_tail); } QhullVertex endVertex() const { return QhullVertex(qhull_qh->vertex_tail); } QhullFacetList facetList() const; diff --git a/cpp/QhullVertex.cpp b/cpp/QhullVertex.cpp index dd483b680e917ad28157b28a03df6eae136dd7fe..1fe869cc4268a8a911bb357eb4691596016a121e 100644 --- a/cpp/QhullVertex.cpp +++ b/cpp/QhullVertex.cpp @@ -29,11 +29,14 @@ s_empty_vertex= {0,0,0,0,0, 0,0}; #//ForEach + +//! Return neighboring facets for a vertex +//! If neither merging nor Voronoi diagram, requires Qhull::defineVertexNeighborFacets() beforehand. QhullFacetSet QhullVertex:: neighborFacets() const { - if(!qh_vertex->neighbors){ - throw QhullError(10034, "Qhull error: neighbors of vertex %d not defined. Need to call defineVertexNeighbors().", id()); + if(!neighborFacetsDefined()){ + throw QhullError(10034, "Qhull error: neighboring facets of vertex %d not defined. Please call Qhull::defineVertexNeighborFacets() beforehand.", id()); } return QhullFacetSet(qh_vertex->neighbors); }//neighborFacets @@ -71,18 +74,20 @@ operator<<(ostream &os, const QhullVertex::PrintVertex &pr) os << " ridgedeleted"; } os << endl; - QhullFacetSetIterator i= v.neighborFacets(); - if(i.hasNext()){ - os << " neighborFacets:"; - int count= 0; - while(i.hasNext()){ - if(++count % 100 == 0){ - os << endl << " "; + if(v.neighborFacetsDefined()){ + QhullFacetSetIterator i= v.neighborFacets(); + if(i.hasNext()){ + os << " neighborFacets:"; + int count= 0; + while(i.hasNext()){ + if(++count % 100 == 0){ + os << endl << " "; + } + QhullFacet f= i.next(); + os << " f" << f.id(); } - QhullFacet f= i.next(); - os << " f" << f.id(); + os << endl; } - os << endl; } return os; }//<< PrintVertex diff --git a/cpp/QhullVertex.h b/cpp/QhullVertex.h index 1b50bf2d434a3ff11f71ee219ecc99bfc01c70df..3b0902acd5aa57affc0961f31fb8cfae1ede14e4 100644 --- a/cpp/QhullVertex.h +++ b/cpp/QhullVertex.h @@ -72,6 +72,8 @@ public: int dimension() const { return (qh_vertex->dim || !isDefined()) ? qh_vertex->dim : UsingLibQhull::globalVertexDimension(); } int id() const { return qh_vertex->id; } bool isDefined() const { return 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 qh_vertex->next; } bool operator==(const QhullVertex &o) const { return qh_vertex==o.qh_vertex; } bool operator!=(const QhullVertex &o) const { return !operator==(o); } diff --git a/cpp/qhulltest/QhullVertex_test.cpp b/cpp/qhulltest/QhullVertex_test.cpp index eb7f18cfa0c2f959b392c766b0135b675dc5dcf5..150dbcf29dfae8e94a54d9ae281a7e8c7736f655 100644 --- a/cpp/qhulltest/QhullVertex_test.cpp +++ b/cpp/qhulltest/QhullVertex_test.cpp @@ -150,6 +150,32 @@ t_io() cout << os.str(); QString s= QString::fromStdString(os.str()); QCOMPARE(s.count("(v"), 10); + QCOMPARE(s.count(": f"), 2); + } + RboxPoints r10("10 D3"); // Without QhullVertex::facetNeighbors + { + Qhull q(r10, ""); + QhullVertex v= q.beginVertex(); + ostringstream os; + os << "\nTry again with simplicial facets. No neighboring facets listed for vertices.\n"; + os << "Vertex and vertices w/o runId:\n"; + os << v; + q.defineVertexNeighborFacets(); + os << "This time with neighborFacets() defined for all vertices:\n"; + os << v; + cout << os.str(); + QString s= QString::fromStdString(os.str()); + QCOMPARE(s.count(": f"), 1); + + Qhull q2(r10, "v"); // Voronoi diagram + QhullVertex v2= q2.beginVertex(); + ostringstream os2; + os2 << "\nTry again with Voronoi diagram of simplicial facets. Neighboring facets automatically defined for vertices.\n"; + os2 << "Vertex and vertices w/o runId:\n"; + os2 << v2; + cout << os2.str(); + QString s2= QString::fromStdString(os2.str()); + QCOMPARE(s2.count(": f"), 1); } }//t_io diff --git a/cpp/qhulltest/Qhull_test.cpp b/cpp/qhulltest/Qhull_test.cpp index 77cba8537767d97f7c30e46a3cdd39352b87ee38..e198f951f1c21c85ea22ef158d59f056e0954dd6 100644 --- a/cpp/qhulltest/Qhull_test.cpp +++ b/cpp/qhulltest/Qhull_test.cpp @@ -316,6 +316,8 @@ t_foreach() q.runQhull(rcube, ""); QCOMPARE(q.facetList().count(), 6); + // defineVertexNeighborFacets() tested in QhullVertex_test::t_io() + QhullFacetList facets(q.beginFacet(), q.endFacet()); QCOMPARE(facets.count(), 6); QCOMPARE(q.firstFacet(), q.beginFacet()); diff --git a/cpp/qhulltest/qhulltest.cpp b/cpp/qhulltest/qhulltest.cpp index 753643cc561816af3802eb917a8dc0150fd819ff..b85f563bddd1237188e48c463c0c3a1ee74f11ea 100644 --- a/cpp/qhulltest/qhulltest.cpp +++ b/cpp/qhulltest/qhulltest.cpp @@ -22,7 +22,7 @@ namespace orgQhull { void addQhullTests(QStringList &args) { - TESTadd_(add_QhullSet_test); //copy + TESTadd_(add_QhullVertex_test); //copy if(args.contains("--all")){ args.removeAll("--all"); diff --git a/index.htm b/index.htm index 2219a3fe921615b2764943ee58490654b5a3df2f..6bdb61150e0e47e7fb0daa09f6afefb0414d8c36 100644 --- a/index.htm +++ b/index.htm @@ -65,7 +65,8 @@ and higher. </p> www.qhull.org <p> <li><a href="http://www.qhull.org/news/qhull-news.html#users">How</a> is Qhull used?</li> - <li><a href="http://citeseerx.ist.psu.edu/showciting?doi=10.1.1.117.405&sort=cite">CiteSeer</a> references to Qhull + <li><a href="http://citeseerx.ist.psu.edu/showciting?doi=10.1.1.117.405&sort=cite">CiteSeer</a> + and <a href="http://scholar.google.com/scholar?cites=6731193060570243661&hl=en&as_sdt=40000000">Google Scholar</a> references to Qhull </p> <li> <a href=http://www.google.com/search?as_q=qhull+-debian+-cvs+-gentoo+-pool+-mirrors&num=100>Google</a> Qhull, diff --git a/src/Changes.txt b/src/Changes.txt index 52039bb37ab0df997924f8915485a361121fb3f4..98fa5ef02f2dd1905de7b7854df01610d6ffe859 100644 --- a/src/Changes.txt +++ b/src/Changes.txt @@ -5,6 +5,7 @@ Need help - The C++ interface needs work. Give it a try and make it better. http://gitorious.org/qhull/ + - Document with Qt conventions using Doxygen (//! and //!<) - Produce conformant triangulations for merged facets using option 'Qt' - Add CMakeLists.txt for qhullcpp, user_eg3, cpp/, and cpp/road If practical, please move CMakeLists.txt to project/ @@ -20,12 +21,19 @@ To do - Create signed tags for Qhull versions - Add FIXUP for known problems and update wiki - Notes to compgeom on conformant triangulation and Voronoi volume - + +------------ +gitorious.org/qhull 2010/03/14 +- Add Qhull::defineVertexFacetNeighbors() for facetNeighbors of vertices. + Automatically called for facet merging and Voronoi diagrams + Do not print QhullVertex::facetNeighbors is !facetNeighborsDefined() +- Fixed type of vertex->neighbors in qh_printvoronoi [no effect on results] +- Removed unnecessary if statement in qh_printvoronoi ------------ gitorious.org/qhull 2010/01/25 -- qh-optf.htm: Add note about order of 'Fn' matching 'Fv' order [Q. Pan] - Fixed src/CMakeLists.txt [M. Moll] +- qh-optf.htm: Add note about order of 'Fn' matching 'Fv' order [Q. Pan] - Add .gitignore with ignored files and directories. - Use .git/info/exclude for locally excluded files. diff --git a/src/io.c b/src/io.c index 1ebea06b268ea0acfa742519e6e1657039ec96fa..f912df4b75dbc7fb49e28ccce10b4a8ec04a64ea 100644 --- a/src/io.c +++ b/src/io.c @@ -3443,7 +3443,7 @@ void qh_printvoronoi(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, if (qh hull_dim == 3) qh_order_vertexneighbors(vertex); else if (qh hull_dim >= 4) - qsort(SETaddr_(vertex->neighbors, vertexT), + qsort(SETaddr_(vertex->neighbors, facetT), (size_t)qh_setsize(vertex->neighbors), sizeof(facetT *), qh_compare_facetvisit); FOREACHneighbor_(vertex) { @@ -3456,11 +3456,9 @@ void qh_printvoronoi(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, if (format == qh_PRINTgeom) { if (vertex) { qh_fprintf(fp, 9262, "%d", numneighbors); - if (vertex) { - FOREACHneighbor_(vertex) { - if (neighbor->visitid && neighbor->visitid < numfacets) - qh_fprintf(fp, 9263, " %d", neighbor->visitid); - } + FOREACHneighbor_(vertex) { + if (neighbor->visitid && neighbor->visitid < numfacets) + qh_fprintf(fp, 9263, " %d", neighbor->visitid); } qh_fprintf(fp, 9264, " # p%d(v%d)\n", vertex_i, vertex->id); }else