<p>Qhull-2015 introduces reentrant Qhull (libqhull_r). Reentrant Qhull uses a qhT* argument instead of global data structures.
The qhT* pointer is the first argument to most Qhull routines. It allows multiple instances of Qhull to run at the same time.
It simplifies the C++ interface to Qhull.
<p>New code should be written with libqhull_r. Existing users of libqhull should consider converting to libqhull_r.
Although libqhull will be supported indefinitely, improvements may not be implemented.
Reentrant qhull is 1-2% slower than non-reentrant qhull.
<p><b>Note:</b> Reentrant Qhull is <i>not</i> thread safe. Do not invoke Qhull routines with the same qhT* pointer from multiple threads.
<h2><ahref="#TOC">»</a><aname="convert">How to convert</a> code to reentrant Qhull</h2>
<p>C++ users need to convert to libqhull_r.
The new C++ interface does a better, but not perfect, job of hiding Qhull's C data structures.
The previous C++ interface was unusual due to Qhull's global data structures.
<p>All other users should consider converting to libqhull_r. The conversion is straight forward.
The original conversion of libqhull to libqhull_r required thousands of changes, mostly global
search and replace. The first run of Qhull (unix_r.c) produced the same
output, and nearly the same log files, as the original (unix.c).
<p>Suggestions to help with conversion.
<ul>
<li>Compare qconvex_r.c with qconvex.c. Define a qhT object and a pointer it. The qhT* pointer is the first argument to most Qhull functions.
Clear <tt>qh_qh-<NOerrext</tt> before calling qh_initflags(). Invoke QHULL_LIB_CHECK to check for a compatible Qhull library.
<li>Compare user_eg2_r.c with user_eg2.c
<li>Compare user_eg_r.c with user_eg.c. If you use qhT before invoking qh_init_A, call qh_zero() to clear the qhT object.
user_eg_r.c includes multiple Qhull runs.
<li>Review user_eg3_r.cpp. As with the other programs, invoke QHULL_LIB_CHECK.
Simple C++ programs should compile as is.
<li>Compare QhullFacet.cpp with the same file in Qhull-2012.1. UsingLibQhull was replaced with the macro QH_TRY_() and '<tt>qh_qh-<NOerrext= true</tt>'.
<li>For detailed notes on libqhull_r, see "libqhull_r (reentrant Qhull)" and "Source code changes for libqhull_r" in <ahref="../src/Changes.txt">Changes.txt</a>.
<li>For detailed notes on libqhullcpp, see "C++ interface" and following sections in <ahref="../src/Changes.txt">Changes.txt</a>.
<li>For regexps and conversion notes, see <ahref="http://www.qhull.org/html/README_r.txt">README_r.txt</a> (unedited).
</ul>
<h2><ahref="#TOC">»</a><aname="64bit">Qhull on 64-bit computers</a></h2>
<p>Qhull compiles for 64-bit hosts. Since the size of a pointer on a 64-bit host is double the size on a 32-bit host,
memory consumption increases about 50% for simplicial facets and up-to 100% for non-simplicial facets.
<p>You can check memory consumption with option <ahref="qh-optt.htm#Ts">Ts</a>. It includes the size of
each data structure:
<ul>
<li>32-bit -- merge 24 ridge 20 vertex 28 facet 88 normal 24 ridge vertices 16 facet vertices or neighbors 20
<li>64-bit -- merge 32 ridge 32 vertex 48 facet 120 normal 32 ridge vertices 40 facet vertices or neighbors 48
</ul>
<p>For Qhull 2015, the maximum identifier for ridges, vertices, and facets was increased
from 24-bits to 32-bits. This allows for larger convex hulls, but may increase the size of
the corresponding data structures. The sizes for Qhull 2012.1 were
A QhullFacetSet is a <ahref="#set-cpp">QhullSet</a> of <ahref="#facet-cpp">QhullFacet</a>. QhullFacetSet may be ordered or unordered. The neighboring facets of a QhullFacet is a QhullFacetSet.
The neighbors of a <ahref="#facet-cpp">QhullFacet</a> is a QhullFacetSet.
The neighbors are ordered for simplicial facets, matching the opposite vertex of the facet.
A QhullPointSet is a <ahref="#set-cpp">QhullSet</a> of <ahref="#point-cpp">QhullPoint</a>. The QhullPointSet of a <ahref="#facet-cpp">QhullFacet</a> is its coplanar points.
A QhullRidgeSet is a <ahref="#set-cpp">QhullSet</a> of <ahref="#ridge-cpp">QhullRidge</a>. Each <ahref="#facet-cpp">QhullFacet</a> contains a QhullRidgeSet.
A QhullVertex is a vertex of the convex hull. A simplicial <ahref="#facet-cpp">QhullFacet</a> has qh.hull_dim-1 vertices. A QhullVertex contains a <ahref="#point-cpp">QhullPoint</a>.
It may list its neighboring <ahref="#facet-cpp">QhullFacet</a>'s.
RboxPoints is a std::vector of point coordinates (<ahref="#point-cpp">QhullPoint</a>).
It's iterator is <ahref="#coordinate-cpp">CoordinateIterator</a>.
</p>
<p>
<code>RboxPoints.appendRandomPoints()</code> appends points from a variety of distributions such as uniformly distributed within a cube and random points on a sphere.
It can also append a cube's vertices or specific points.
</p>
<h3><ahref="#TOC">»</a><aname="questions-cpp">Cpp questions for Qhull</a></h3>
Developing C++ code requires many conventions, idioms, and technical details.
The following questions have either
mystified the author or do not have a clear answer. See also
<ahref="http://www.qhull.org/road/road-faq/xml/cpp-guideline.xml">C++ and Perl Guidelines</a>.
and FIXUP notes in the code.
Please add notes to <ahref="http://github.com/qhull/qhull/wiki">Qhull Wiki</a>.
<ul>
<li>FIXUP QH11028 Should return reference, but get reference to temporary
<li>How to avoid copy constructor while logging, maybeThrowQhullMessage()
<li>How to configure Qhull output. Trace and results should go to stdout/stderr
<li>Qhull and RboxPoints messaging. e.g., ~Qhull, hasQhullMessage(). Rename them as QhullErrorMessage?
<li>How to add additional output to an error message, e.g., qh_setprint
<li>Is idx the best name for an index? It's rather cryptic, but BSD strings.h defines index().
<li>Qhull::feasiblePoint Qhull::useOutputStream as field or getter?
<li>Define virtual functions for user customization of Qhull (e.g., qh_fprintf, qh_memfree,etc.)
<li>Figure out RoadError::global_log. clearQhullMessage currently clearGlobalLog
<li>Should the false QhullFacet be NULL or empty? e.g., QhullFacet::tricoplanarOwner() and QhullFacetSet::end()
<li>Should output format for floats be predefined (qh_REAL_1, 2.2g, 10.7g) or as currently set for stream
<li>Should cout << !point.defined() be blank or 'undefined'
<li>Infinite point as !defined()
<li>qlist and qlinkedlist define pointer, reference, size_type, difference_type, const_pointer, const_reference for the class but not for iterator and const_iterator