Tesseract
Motion Planning Environment
Loading...
Searching...
No Matches
vhacdVHACD.h
Go to the documentation of this file.
1/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
2All rights reserved.
3
4
5Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6following conditions are met:
7
81. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
9disclaimer.
10
112. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
12disclaimer in the documentation and/or other materials provided with the distribution.
13
143. The names of the contributors may not be used to endorse or promote products derived from this software without
15specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*/
25#pragma once
26
29
30#ifdef OPENCL_FOUND
31#ifdef __MACH__
32#include <OpenCL/cl.h>
33#else
34#include <CL/cl.h>
35#endif
36#endif // OPENCL_FOUND
37
41#include <vector>
42#include <array>
43
44#define USE_THREAD 1
45#define OCL_MIN_NUM_PRIMITIVES 4096
46#define CH_APP_MIN_NUM_PRIMITIVES 64000
47
48namespace tesseract_collision
49{
50namespace VHACD
51{
52class VHACD : public IVHACD
53{
54public:
57 {
58#if USE_THREAD == 1 && _OPENMP
59 m_ompNumProcessors = 2 * omp_get_num_procs();
60 omp_set_num_threads(m_ompNumProcessors);
61#else // USE_THREAD == 1 && _OPENMP
63#endif // USE_THREAD == 1 && _OPENMP
64#ifdef CL_VERSION_1_1
65 m_oclWorkGroupSize = 0;
66 m_oclDevice = nullptr;
67 m_oclQueue = nullptr;
68 m_oclKernelComputePartialVolumes = nullptr;
69 m_oclKernelComputeSum = nullptr;
70#endif // CL_VERSION_1_1
71 Init();
72 }
73 uint32_t GetNConvexHulls() const override { return (uint32_t)m_convexHulls.Size(); }
74 void Cancel() override { SetCancel(true); }
75 void GetConvexHull(uint32_t index, ConvexHull& ch) const override
76 {
77 Mesh* mesh = m_convexHulls[index];
78 ch.m_nPoints = (uint32_t)mesh->GetNPoints();
79 ch.m_nTriangles = (uint32_t)mesh->GetNTriangles();
80 ch.m_points = mesh->GetPoints();
81 ch.m_triangles = (uint32_t*)mesh->GetTriangles();
82 ch.m_volume = mesh->ComputeVolume();
83 Vec3<double>& center = mesh->ComputeCenter();
84 ch.m_center[0] = center.X();
85 ch.m_center[1] = center.Y();
86 ch.m_center[2] = center.Z();
87 }
88 void Clean() override
89 {
90 if (mRaycastMesh)
91 {
93 mRaycastMesh = nullptr;
94 }
95 delete m_volume;
96 delete m_pset;
97 size_t nCH = m_convexHulls.Size();
98 for (size_t p = 0; p < nCH; ++p)
99 {
100 delete m_convexHulls[p];
101 }
102 m_convexHulls.Clear();
103 Init();
104 }
105 void Release() override { delete this; }
106 bool Compute(float const* points,
107 uint32_t nPoints,
108 uint32_t const* triangles,
109 uint32_t nTriangles,
110 const Parameters& params) override;
111 bool Compute(double const* points,
112 uint32_t nPoints,
113 uint32_t const* triangles,
114 uint32_t nTriangles,
115 const Parameters& params) override;
116 bool OCLInit(void const* oclDevice, VHACD::IVHACD::IUserLogger const* logger = nullptr) override;
117 bool OCLRelease(IUserLogger const* logger = nullptr) override;
118
119 virtual bool ComputeCenterOfMass(std::array<double, 3>& centerOfMass) const override;
120
121private:
122 void SetCancel(bool cancel)
123 {
125 m_cancel = cancel;
127 }
129 {
131 bool cancel = m_cancel;
133 return cancel;
134 }
135 void Update(const double stageProgress, const double operationProgress, const Parameters& params)
136 {
137 m_stageProgress = stageProgress;
138 m_operationProgress = operationProgress;
139 if (params.m_callback)
140 {
141 params.m_callback->Update(
143 }
144 }
145 void Init()
146 {
147 if (mRaycastMesh)
148 {
150 mRaycastMesh = nullptr;
151 }
152 memset(m_rot, 0, sizeof(double) * 9);
153 m_dim = 64;
154 m_volume = 0;
155 m_volumeCH0 = 0.0;
156 m_pset = 0;
157 m_overallProgress = 0.0;
158 m_stageProgress = 0.0;
160 m_stage = "";
161 m_operation = "";
162 m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0.0;
163 m_rot[0][0] = m_rot[1][1] = m_rot[2][2] = 1.0;
164 SetCancel(false);
165 }
166 void ComputePrimitiveSet(const Parameters& params);
167 void ComputeACD(const Parameters& params);
168 void MergeConvexHulls(const Parameters& params);
169 void SimplifyConvexHull(Mesh* const ch, const size_t nvertices, const double minVolume);
170 void SimplifyConvexHulls(const Parameters& params);
171 void ComputeBestClippingPlane(const PrimitiveSet* inputPSet,
172 const double volume,
173 const SArray<Plane>& planes,
174 const Vec3<double>& preferredCuttingDirection,
175 const double w,
176 const double alpha,
177 const double beta,
178 const int32_t convexhullDownsampling,
179 const double progress0,
180 const double progress1,
181 Plane& bestPlane,
182 double& minConcavity,
183 const Parameters& params);
184 template <class T>
185 void AlignMesh(const T* const points,
186 const uint32_t stridePoints,
187 const uint32_t nPoints,
188 const int32_t* const triangles,
189 const uint32_t strideTriangles,
190 const uint32_t nTriangles,
191 const Parameters& params)
192 {
193 if (GetCancel() || !params.m_pca)
194 {
195 return;
196 }
197 m_timer.Tic();
198
199 m_stage = "Align mesh";
200 m_operation = "Voxelization";
201
202 std::ostringstream msg;
203 if (params.m_logger)
204 {
205 msg << "+ " << m_stage << std::endl;
206 params.m_logger->Log(msg.str().c_str());
207 }
208
209 Update(0.0, 0.0, params);
210 if (GetCancel())
211 {
212 return;
213 }
214 m_dim = (size_t)(pow((double)params.m_resolution, 1.0 / 3.0) + 0.5);
215 Volume volume;
216 volume.Voxelize(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, m_dim, m_barycenter, m_rot);
217 size_t n = volume.GetNPrimitivesOnSurf() + volume.GetNPrimitivesInsideSurf();
218 Update(50.0, 100.0, params);
219
220 if (params.m_logger)
221 {
222 msg.str("");
223 msg << "\t dim = " << m_dim << "\t-> " << n << " voxels" << std::endl;
224 params.m_logger->Log(msg.str().c_str());
225 }
226 if (GetCancel())
227 {
228 return;
229 }
230 m_operation = "PCA";
231 Update(50.0, 0.0, params);
233 m_overallProgress = 1.0;
234 Update(100.0, 100.0, params);
235
236 m_timer.Toc();
237 if (params.m_logger)
238 {
239 msg.str("");
240 msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl;
241 params.m_logger->Log(msg.str().c_str());
242 }
243 }
244 template <class T>
245 void VoxelizeMesh(const T* const points,
246 const uint32_t stridePoints,
247 const uint32_t nPoints,
248 const int32_t* const triangles,
249 const uint32_t strideTriangles,
250 const uint32_t nTriangles,
251 const Parameters& params)
252 {
253 if (GetCancel())
254 {
255 return;
256 }
257
258 m_timer.Tic();
259 m_stage = "Voxelization";
260
261 std::ostringstream msg;
262 if (params.m_logger)
263 {
264 msg << "+ " << m_stage << std::endl;
265 params.m_logger->Log(msg.str().c_str());
266 }
267
268 delete m_volume;
269 m_volume = 0;
270 int32_t iteration = 0;
271 const int32_t maxIteration = 5;
272 double progress = 0.0;
273 while (iteration++ < maxIteration && !m_cancel)
274 {
275 msg.str("");
276 msg << "Iteration " << iteration;
277 m_operation = msg.str();
278
279 progress = iteration * 100.0 / maxIteration;
280 Update(progress, 0.0, params);
281
282 m_volume = new Volume;
284 points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, m_dim, m_barycenter, m_rot);
285
286 Update(progress, 100.0, params);
287
289 if (params.m_logger)
290 {
291 msg.str("");
292 msg << "\t dim = " << m_dim << "\t-> " << n << " voxels" << std::endl;
293 params.m_logger->Log(msg.str().c_str());
294 }
295
296 double a = pow((double)(params.m_resolution) / n, 0.33);
297 size_t dim_next = (size_t)(m_dim * a + 0.5);
298 if (n < params.m_resolution && iteration < maxIteration &&
299 m_volume->GetNPrimitivesOnSurf() < params.m_resolution / 8 && m_dim != dim_next)
300 {
301 delete m_volume;
302 m_volume = 0;
303 m_dim = dim_next;
304 }
305 else
306 {
307 break;
308 }
309 }
310 m_overallProgress = 10.0;
311 Update(100.0, 100.0, params);
312
313 m_timer.Toc();
314 if (params.m_logger)
315 {
316 msg.str("");
317 msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl;
318 params.m_logger->Log(msg.str().c_str());
319 }
320 }
321 template <class T>
322 bool ComputeACD(const T* const points,
323 const uint32_t nPoints,
324 const uint32_t* const triangles,
325 const uint32_t nTriangles,
326 const Parameters& params)
327 {
328 Init();
329 if (params.m_projectHullVertices)
330 {
331 mRaycastMesh = RaycastMesh::createRaycastMesh(nPoints, points, nTriangles, (const uint32_t*)triangles);
332 }
333 if (params.m_oclAcceleration)
334 {
335 // build kernels
336 }
337 AlignMesh(points, 3, nPoints, (int32_t*)triangles, 3, nTriangles, params);
338 VoxelizeMesh(points, 3, nPoints, (int32_t*)triangles, 3, nTriangles, params);
339 ComputePrimitiveSet(params);
340 ComputeACD(params);
341 MergeConvexHulls(params);
342 SimplifyConvexHulls(params);
343 if (params.m_oclAcceleration)
344 {
345 // Release kernels
346 }
347 if (GetCancel())
348 {
349 Clean();
350 return false;
351 }
352 return true;
353 }
354
355private:
358 std::string m_stage;
359 std::string m_operation;
363 double m_rot[3][3];
367 size_t m_dim;
373#ifdef CL_VERSION_1_1
374 cl_device_id* m_oclDevice;
375 cl_context m_oclContext;
376 cl_program m_oclProgram;
377 cl_command_queue* m_oclQueue;
378 cl_kernel* m_oclKernelComputePartialVolumes;
379 cl_kernel* m_oclKernelComputeSum;
380 size_t m_oclWorkGroupSize;
381#endif // CL_VERSION_1_1
382};
383} // namespace VHACD
384} // namespace tesseract_collision
uint32_t m_nTriangles
Definition: VHACD.h:106
double m_volume
Definition: VHACD.h:107
double * m_points
Definition: VHACD.h:103
uint32_t m_nPoints
Definition: VHACD.h:105
std::array< double, 3 > m_center
Definition: VHACD.h:108
uint32_t * m_triangles
Definition: VHACD.h:104
virtual void Update(double overallProgress, double stageProgress, double operationProgress, const std::string &stage, const std::string &operation)=0
virtual void Log(const std::string &msg) const =0
IUserLogger * m_logger
Definition: VHACD.h:140
bool m_projectHullVertices
Definition: VHACD.h:150
uint32_t m_pca
Definition: VHACD.h:145
uint32_t m_resolution
Definition: VHACD.h:141
IUserCallback * m_callback
Definition: VHACD.h:139
uint32_t m_oclAcceleration
Definition: VHACD.h:148
Triangular mesh data structure.
Definition: vhacdMesh.h:80
Definition: vhacdMutex.h:88
void Unlock(void)
Definition: vhacdMutex.h:132
void Lock(void)
Definition: vhacdMutex.h:111
Definition: vhacdVolume.h:59
Definition: vhacdRaycastMesh.h:12
static RaycastMesh * createRaycastMesh(uint32_t vcount, const double *vertices, uint32_t tcount, const uint32_t *indices)
Definition: vhacdRaycastMesh.cpp:176
SArray.
Definition: vhacdSArray.h:42
Definition: vhacdTimer.h:97
double GetElapsedTime()
Definition: vhacdTimer.h:103
void Toc()
Definition: vhacdTimer.h:102
void Tic()
Definition: vhacdTimer.h:101
Definition: vhacdVHACD.h:53
size_t m_dim
Definition: vhacdVHACD.h:367
bool OCLInit(void const *oclDevice, VHACD::IVHACD::IUserLogger const *logger=nullptr) override
Definition: VHACD.cpp:234
double m_rot[3][3]
Definition: vhacdVHACD.h:363
RaycastMesh * mRaycastMesh
Definition: vhacdVHACD.h:356
Volume * m_volume
Definition: vhacdVHACD.h:368
void Release() override
Definition: vhacdVHACD.h:105
virtual bool ComputeCenterOfMass(std::array< double, 3 > &centerOfMass) const override
Definition: VHACD.cpp:1787
void VoxelizeMesh(const T *const points, const uint32_t stridePoints, const uint32_t nPoints, const int32_t *const triangles, const uint32_t strideTriangles, const uint32_t nTriangles, const Parameters &params)
Definition: vhacdVHACD.h:245
double m_volumeCH0
Definition: vhacdVHACD.h:364
void SimplifyConvexHulls(const Parameters &params)
Definition: VHACD.cpp:1744
bool m_cancel
Definition: vhacdVHACD.h:371
void GetConvexHull(uint32_t index, ConvexHull &ch) const override
Definition: vhacdVHACD.h:75
std::string m_operation
Definition: vhacdVHACD.h:359
bool OCLRelease(IUserLogger const *logger=nullptr) override
Definition: VHACD.cpp:382
Mutex m_cancelMutex
Definition: vhacdVHACD.h:370
void SetCancel(bool cancel)
Definition: vhacdVHACD.h:122
bool Compute(float const *points, uint32_t nPoints, uint32_t const *triangles, uint32_t nTriangles, const Parameters &params) override
Definition: VHACD.cpp:521
void Update(const double stageProgress, const double operationProgress, const Parameters &params)
Definition: vhacdVHACD.h:135
double m_operationProgress
Definition: vhacdVHACD.h:362
uint32_t GetNConvexHulls() const override
Definition: vhacdVHACD.h:73
void Cancel() override
Definition: vhacdVHACD.h:74
Timer m_timer
Definition: vhacdVHACD.h:366
SArray< Mesh * > m_convexHulls
Definition: vhacdVHACD.h:357
Vec3< double > m_barycenter
Definition: vhacdVHACD.h:365
void ComputePrimitiveSet(const Parameters &params)
Definition: VHACD.cpp:459
void ComputeACD(const Parameters &params)
Definition: VHACD.cpp:1159
bool ComputeACD(const T *const points, const uint32_t nPoints, const uint32_t *const triangles, const uint32_t nTriangles, const Parameters &params)
Definition: vhacdVHACD.h:322
int32_t m_ompNumProcessors
Definition: vhacdVHACD.h:372
double m_overallProgress
Definition: vhacdVHACD.h:360
PrimitiveSet * m_pset
Definition: vhacdVHACD.h:369
void AlignMesh(const T *const points, const uint32_t stridePoints, const uint32_t nPoints, const int32_t *const triangles, const uint32_t strideTriangles, const uint32_t nTriangles, const Parameters &params)
Definition: vhacdVHACD.h:185
bool GetCancel()
Definition: vhacdVHACD.h:128
std::string m_stage
Definition: vhacdVHACD.h:358
double m_stageProgress
Definition: vhacdVHACD.h:361
void MergeConvexHulls(const Parameters &params)
Definition: VHACD.cpp:1509
void Init()
Definition: vhacdVHACD.h:145
void ComputeBestClippingPlane(const PrimitiveSet *inputPSet, const double volume, const SArray< Plane > &planes, const Vec3< double > &preferredCuttingDirection, const double w, const double alpha, const double beta, const int32_t convexhullDownsampling, const double progress0, const double progress1, Plane &bestPlane, double &minConcavity, const Parameters &params)
Definition: VHACD.cpp:783
void SimplifyConvexHull(Mesh *const ch, const size_t nvertices, const double minVolume)
Definition: VHACD.cpp:1648
VHACD()
Constructor.
Definition: vhacdVHACD.h:56
void Clean() override
Definition: vhacdVHACD.h:88
Vector dim 3.
Definition: vhacdVector.h:37
T & Y()
Definition: vhacdVector.inl:18
T & X()
Definition: vhacdVector.inl:13
T & Z()
Definition: vhacdVector.inl:23
Definition: vhacdVolume.h:232
size_t GetNPrimitivesOnSurf() const
Definition: vhacdVolume.h:265
void Voxelize(const T *const points, const uint32_t stridePoints, const uint32_t nPoints, const int32_t *const triangles, const uint32_t strideTriangles, const uint32_t nTriangles, const size_t dim, const Vec3< double > &barycenter, const double(&rot)[3][3])
Voxelize.
Definition: vhacdVolume.h:361
void AlignToPrincipalAxes(double(&rot)[3][3]) const
Definition: vhacdVolume.cpp:1100
size_t GetNPrimitivesInsideSurf() const
Definition: vhacdVolume.h:266
Definition: polygon_mesh.h:46
Common Tesseract Macros.
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
Definition: macros.h:71
Definition: create_convex_hull.cpp:36
Definition: bullet_cast_bvh_manager.h:49
Definition: vhacdMesh.h:43
auto mesh
Definition: tesseract_geometry_unit.cpp:25