3 #ifdef HPP_FCL_HAS_QHULL
28 p0 = convex_tri->
points[tri[0]];
30 p2 = convex_tri->
points[tri[2]];
32 Vec3f barycentre_tri, center_barycenter;
33 barycentre_tri = (p0 +
p1 + p2) / 3;
34 center_barycenter = barycentre_tri - convex_tri->
center;
36 Vec3f edge_tri1, edge_tri2, n_tri;
39 n_tri = edge_tri1.cross(edge_tri2);
41 if (center_barycenter.dot(n_tri) < 0) {
42 tri.
set(tri[1], tri[0], tri[2]);
48 const char* qhullCommand) {
49 #ifdef HPP_FCL_HAS_QHULL
51 throw std::invalid_argument(
52 "You shouldn't use this function with less than"
55 assert(pts[0].
data() + 3 == pts[1].
data());
59 qhullCommand ? qhullCommand : (keepTriangles ?
"Qt" :
"");
60 qh.runQhull(
"", 3,
static_cast<int>(
num_points), pts[0].data(), command);
63 if (
qh.hasQhullMessage()) std::cerr <<
qh.qhullMessage() << std::endl;
64 throw std::logic_error(
"Qhull failed");
67 typedef std::size_t index_type;
68 typedef int size_type;
71 std::vector<int> pts_to_vertices(
num_points, -1);
74 int nvertex = (
qh.vertexCount());
78 for (QhullVertexList::const_iterator
v = vertexList.begin();
79 v != vertexList.end(); ++
v) {
80 QhullPoint pt((*v).point());
81 pts_to_vertices[(size_t)pt.id()] = (int)i_vertex;
82 vertices[i_vertex] =
Vec3f(pt[0], pt[1], pt[2]);
85 assert(i_vertex == nvertex);
93 convex->
initialize(
true, vertices,
static_cast<unsigned int>(nvertex));
97 std::vector<std::set<index_type> > nneighbors(
static_cast<size_t>(nvertex));
99 convex_tri->
num_polygons =
static_cast<unsigned int>(
qh.facetCount());
104 unsigned int c_nneighbors = 0;
105 unsigned int i_polygon = 0;
108 for (QhullFacet facet =
qh.beginFacet(); facet !=
qh.endFacet();
109 facet = facet.next()) {
110 if (facet.isSimplicial()) {
112 QhullVertexSet f_vertices(facet.vertices());
113 size_t n =
static_cast<size_t>(f_vertices.count());
117 pts_to_vertices[
static_cast<size_t>(f_vertices[0].point().
id())]),
119 pts_to_vertices[
static_cast<size_t>(f_vertices[1].point().
id())]),
120 static_cast<size_t>(pts_to_vertices[
static_cast<size_t>(
121 f_vertices[2].point().
id())]));
124 convex_tri->
polygons[i_polygon++] = tri;
126 for (
size_t j = 0; j < n; ++j) {
127 size_t i = (j == 0) ? n - 1 : j - 1;
128 size_t k = (j == n - 1) ? 0 : j + 1;
130 if (nneighbors[tri[j]].insert(tri[i]).second) c_nneighbors++;
131 if (nneighbors[tri[j]].insert(tri[k]).second) c_nneighbors++;
135 throw std::invalid_argument(
136 "You requested to keep triangles so you "
137 "must pass option \"Qt\" to qhull via the qhull command argument.");
143 for (size_type j = 0; j < f_ridges.count(); ++j) {
144 assert(f_ridges[j].vertices().count() == 2);
145 int pi = pts_to_vertices[
static_cast<size_t>(
146 f_ridges[j].vertices()[0].point().id())],
147 pj = pts_to_vertices[
static_cast<size_t>(
148 f_ridges[j].vertices()[1].point().id())];
150 if (nneighbors[
static_cast<size_t>(pj)]
151 .insert(
static_cast<size_t>(pi))
154 if (nneighbors[
static_cast<size_t>(pi)]
155 .insert(
static_cast<size_t>(pj))
161 assert(!keepTriangles || i_polygon ==
qh.facetCount());
164 convex->
nneighbors_ =
new unsigned int[c_nneighbors];
166 for (
size_t i = 0; i < static_cast<size_t>(nvertex); ++i) {
168 if (nneighbors[i].size() >= (std::numeric_limits<unsigned char>::max)())
169 throw std::logic_error(
"Too many neighbors.");
170 n.
count_ = (
unsigned char)nneighbors[i].size();
173 std::copy(nneighbors[i].begin(), nneighbors[i].end(), p_nneighbors);
175 assert(p_nneighbors == convex->
nneighbors_ + c_nneighbors);
178 throw std::logic_error(
179 "Library built without qhull. Cannot build object of this type.");