Main Page Class List Class Members

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