3 #ifdef HPP_FCL_HAS_QHULL 28 p0 = convex_tri->
points[tri[0]];
29 p1 = convex_tri->
points[tri[1]];
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 50 if (num_points <= 3) {
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());
101 convex_tri->computeCenter();
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.");
static ConvexBase * convexHull(const Vec3f *points, unsigned int num_points, bool keepTriangles, const char *qhullCommand=NULL)
Build a convex hull based on Qhull library and store the vertices and optionally the triangles...
void reorderTriangle(const Convex< Triangle > *convex_tri, Triangle &tri)
A QhullFacet is the C++ equivalent to Qhull's facetT*.
unsigned int num_polygons
ConvexBase()
Construct an uninitialized convex object Initialization is done with ConvexBase::initialize.
PolygonT * polygons
An array of PolygonT object. PolygonT should contains a list of vertices for each polygon...
#define HPP_FCL_UNUSED_VARIABLE(var)
QhullSet< QhullRidge > QhullRidgeSet
Interface to Qhull from C++.
void initialize(bool ownStorage, Vec3f *points_, unsigned int num_points_)
Initialize the points of the convex shape This also initializes the ConvexBase::center.
void set(index_type p1, index_type p2, index_type p3)
Set the vertex indices of the triangle.
Triangle with 3 indices for points.
Base for convex polytope.
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
QhullLinkedList< QhullVertex > QhullVertexList
Vec3f center
center of the convex polytope, this is used for collision: center is guaranteed in the internal of th...
unsigned int * nneighbors_
Vec3f * points
An array of the points of the polygon.