ClSurface.hpp
Go to the documentation of this file.
1 
28 #ifndef __ClSurface_H
29 #define __ClSurface_H
30 
35 
36 #include <boost/filesystem.hpp>
37 #include <boost/shared_array.hpp>
38 #include <string.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 
42 #define CL_HPP_TARGET_OPENCL_VERSION 120
43 #define CL_USE_DEPRECATED_OPENCL_1_2_APIS
44 #define __CL_ENABLE_EXCEPTIONS
45 
46 #if defined(__APPLE__) || defined(__MACOSX)
47  #include <OpenCL/opencl.h>
48 #else
49  #include <CL/cl.h>
50 #endif
52 
53 #define MAX_SOURCE_SIZE (0x1024)
54 
55 namespace lvr2
56 {
57 
58 typedef boost::shared_array<float> floatArr;
59 
60 using Vec = BaseVector<float>;
61 typedef QueryPoint<Vec> QueryPointC;
62 
63 class ClSurface {
64 public:
65  ClSurface(floatArr& points, size_t num_points, int device = 0);
66  ~ClSurface();
67 
72  void calculateNormals();
73 
79  void getNormals(floatArr output_normals);
80 
88  void setKn(int kn);
89 
97  void setKi(int ki);
98 
106  void setKd(int kd);
107 
116  void setFlippoint(float v_x, float v_y, float v_z);
117 
124  void setMethod(std::string method);
125 
130  void setReconstructionMode(bool mode = true);
131 
136  void distances(std::vector<QueryPoint<Vec> >& query_points, float voxel_size);
137 
138  void freeGPU();
139 
140 private:
141 
142  void init();
143 
144  const char *getErrorString(cl_int error);
145 
146  void initKdTree();
147 
148  void getDeviceInformation(int platform_id=0, int device_id=0);
149 
150  void loadEstimationKernel();
151 
153 
154  void initCl();
155 
156  void finalizeCl();
157 
158  // V->points and normals
162 
164  boost::shared_ptr<LBKdTree> kd_tree_gen;
165 
166  float m_vx, m_vy, m_vz;
167  int m_k, m_ki, m_kd;
168 
169 
172 
173  // Device Information
174  cl_platform_id m_platform_id;
175  cl_device_id m_device_id;
176  cl_uint m_mps;
179  cl_int m_ret;
180  cl_context m_context;
181  cl_command_queue m_command_queue;
182  cl_program m_program_es;
183  cl_program m_program_in;
186 
187  cl_mem D_V;
190  cl_mem D_Normals;
191 
192 
194 "unsigned int GetKdTreePosition(__global const float* D_kd_tree_values,"
195 "const unsigned int num_values,__global const unsigned char* D_kd_tree_splits,"
196 "const unsigned int num_splits, float x, float y, float z) \n"
197 "{ \n"
198 " unsigned int pos = 0; \n"
199 " unsigned int current_dim = 0; \n"
200 " while(pos < num_splits) \n"
201 " { \n"
202 " current_dim = (unsigned int)(D_kd_tree_splits[pos]); \n"
203 " if(current_dim == 0) \n"
204 " { \n"
205 " if(x <= D_kd_tree_values[pos] ) \n"
206 " { \n"
207 " pos = pos*2+1; \n"
208 " } else { \n"
209 " pos = pos*2+2; \n"
210 " } \n"
211 " } else if(current_dim == 1) { \n"
212 " if(y <= D_kd_tree_values[pos] ){ \n"
213 " pos = pos*2+1; \n"
214 " }else{ \n"
215 " pos = pos*2+2; \n"
216 " } \n"
217 " } else { \n"
218 " if(z <= D_kd_tree_values[pos] ){ \n"
219 " pos = pos*2+1; \n"
220 " }else{ \n"
221 " pos = pos*2+2; \n"
222 " } \n"
223 " } \n"
224 " } \n"
225 " return pos; \n"
226 "} \n"
227 " \n"
228 "__kernel void NormalEstimationKernel(__global const float* D_V, const unsigned int num_points,"
229 "__global const float* D_kd_tree_values, const unsigned int num_values,"
230 "__global const unsigned char* D_kd_tree_splits , const unsigned int num_splits,"
231 "__global float* D_Normals, const unsigned int num_pointnormals,const unsigned int k,"
232 "const float flip_x, const float flip_y, const float flip_z) \n"
233 "{ \n"
234 " unsigned int loc_id = get_local_id(0); \n"
235 " unsigned int loc_size = get_local_size(0); \n"
236 " unsigned int glob_id = get_global_id(0); \n"
237 " unsigned int glob_size = get_global_size(0); \n"
238 " unsigned int group_id = get_group_id(0); \n"
239 " unsigned int group_size = get_num_groups(0); \n"
240 " unsigned int tid = glob_id; \n"
241 " const unsigned int offset = glob_size; \n"
242 " for(;tid < num_points; tid += offset) \n"
243 " { \n"
244 " unsigned int pos = GetKdTreePosition(D_kd_tree_values, "
245 "num_values,D_kd_tree_splits, num_splits,D_V[tid * 3], D_V[tid * 3 + 1], D_V[tid * 3 +2] ); \n"
246 " unsigned int vertex_index = (unsigned int)(D_kd_tree_values[pos]+ 0.5); \n"
247 " if(vertex_index < num_points) \n"
248 " { \n"
249 " float vertex_x = D_V[ vertex_index * 3 + 0 ]; \n"
250 " float vertex_y = D_V[ vertex_index * 3 + 1 ]; \n"
251 " float vertex_z = D_V[ vertex_index * 3 + 2 ]; \n"
252 " unsigned int nearest_index; \n"
253 " int start = pos-(k/2); \n"
254 " int end = pos+((k+1)/2); \n"
255 " int correct = 0; \n"
256 " if(start < num_splits) \n"
257 " { \n"
258 " correct = num_splits - start; \n"
259 " }else if(end > num_values) \n"
260 " { \n"
261 " correct = num_values - end; \n"
262 " } \n"
263 " start += correct; \n"
264 " end += correct; \n"
265 " float result_x = 0.0; \n"
266 " float result_y = 0.0; \n"
267 " float result_z = 0.0; \n"
268 " float xx = 0.0; \n"
269 " float xy = 0.0; \n"
270 " float xz = 0.0; \n"
271 " float yy = 0.0; \n"
272 " float yz = 0.0; \n"
273 " float zz = 0.0; \n"
274 " for(unsigned int i = start; i < end && i<num_values; i++ ) \n"
275 " { \n"
276 " if(i != pos) \n"
277 " { \n"
278 " nearest_index = (unsigned int)(D_kd_tree_values[i]+ 0.5); \n"
279 " if(nearest_index < num_points) \n"
280 " { \n"
281 " float rx = D_V[ nearest_index * 3 + 0 ] - vertex_x; \n"
282 " float ry = D_V[ nearest_index * 3 + 1 ] - vertex_y; \n"
283 " float rz = D_V[ nearest_index * 3 + 2 ] - vertex_z; \n"
284 " xx += rx * rx; \n"
285 " xy += rx * ry; \n"
286 " xz += rx * rz; \n"
287 " yy += ry * ry; \n"
288 " yz += ry * rz; \n"
289 " zz += rz * rz; \n"
290 " } \n"
291 " } \n"
292 " } \n"
293 " float det_x = yy * zz - yz * yz; \n"
294 " float det_y = xx * zz - xz * xz; \n"
295 " float det_z = xx * yy - xy * xy; \n"
296 " float dir_x; \n"
297 " float dir_y; \n"
298 " float dir_z; \n"
299 " if( det_x >= det_y && det_x >= det_z) \n"
300 " { \n"
301 " dir_x = 1.0; \n"
302 " dir_y = (xz * yz - xy * zz) / det_x; \n"
303 " dir_z = (xy * yz - xz * yy) / det_x; \n"
304 " } \n"
305 " else if( det_y >= det_x && det_y >= det_z) \n"
306 " { \n"
307 " dir_x = (yz * xz - xy * zz) / det_y; \n"
308 " dir_y = 1.0; \n"
309 " dir_z = (xy * xz - yz * xx) / det_y; \n"
310 " } \n"
311 " else{ \n"
312 " dir_x = (yz * xy - xz * yy ) / det_z; \n"
313 " dir_y = (xz * xy - yz * xx ) / det_z; \n"
314 " dir_z = 1.0; \n"
315 " } \n"
316 " float invnorm = 1/sqrt( dir_x * dir_x + dir_y * dir_y + dir_z * dir_z ); \n"
317 " result_x = dir_x * invnorm; \n"
318 " result_y = dir_y * invnorm; \n"
319 " result_z = dir_z * invnorm; \n"
320 " float x_dir = flip_x - vertex_x; \n"
321 " float y_dir = flip_y - vertex_y; \n"
322 " float z_dir = flip_z - vertex_z; \n"
323 " float scalar = x_dir * result_x + y_dir * result_y + z_dir * result_z; \n"
324 " if(scalar < 0) \n"
325 " { \n"
326 " result_x = -result_x; \n"
327 " result_y = -result_y; \n"
328 " result_z = -result_z; \n"
329 " } \n"
330 " D_Normals[tid * 3 ] = result_x; \n"
331 " D_Normals[tid * 3 + 1 ] = result_y; \n"
332 " D_Normals[tid * 3 + 2 ] = result_z; \n"
333 " } \n"
334 " } \n"
335 "} \n";
336 
338 "float getGaussianFactor(const unsigned int index, const unsigned int middle_i, "
339 "const unsigned int ki, const float norm) \n"
340 "{ \n"
341 " float val = (float)(index); \n"
342 " float middle = (float)(middle_i); \n"
343 " float ki_2 = (float)(ki)/2.0; \n"
344 " if(val > middle) \n"
345 " { \n"
346 " val = val - middle; \n"
347 " }else{ \n"
348 " val = middle - val; \n"
349 " } \n"
350 " if(val > ki_2) \n"
351 " { \n"
352 " return 0.0; \n"
353 " }else{ \n"
354 " float border_val = 0.2; \n"
355 " float gaussian = 1.0 - pow((float)val/ki_2, (float)2.0) * (1.0-border_val); \n"
356 " return gaussian * norm; \n"
357 " } \n"
358 "} \n"
359 " \n"
360 "__kernel void NormalInterpolationKernel(__global float* D_kd_tree_values,"
361 "const unsigned int num_values, __global float* D_kd_tree_splits, "
362 "const unsigned int num_splits, __global float* D_Normals, "
363 "const unsigned int num_pointnormals, const unsigned int ki) \n"
364 "{ \n"
365 " unsigned int loc_id = get_local_id(0); \n"
366 " unsigned int loc_size = get_local_size(0); \n"
367 " unsigned int glob_id = get_global_id(0); \n"
368 " unsigned int glob_size = get_global_size(0); \n"
369 " unsigned int group_id = get_group_id(0); \n"
370 " unsigned int group_size = get_num_groups(0); \n"
371 " unsigned int tid = glob_id; \n"
372 " const unsigned int offset = glob_size; \n"
373 " for(;tid < num_pointnormals; tid += offset) \n"
374 " { \n"
375 " int c = 0; \n"
376 " unsigned int offset = num_splits; \n"
377 " unsigned int query_index = (unsigned int)(D_kd_tree_values[offset + tid]+ 0.5); \n"
378 " unsigned int nearest_index; \n"
379 " float gaussian = 5.0; \n"
380 " if(query_index < num_pointnormals) \n"
381 " { \n"
382 " float n_x = D_Normals[query_index * 3 + 0]; \n"
383 " float n_y = D_Normals[query_index * 3 + 1]; \n"
384 " float n_z = D_Normals[query_index * 3 + 2]; \n"
385 " if(tid > 1) \n"
386 " { \n"
387 " for(unsigned int i = tid-1; i > 0 && c < ki/2; i--,c++ ) \n"
388 " { \n"
389 " nearest_index = (unsigned int)(D_kd_tree_values[i + offset]+ 0.5); \n"
390 " if(nearest_index < num_pointnormals) \n"
391 " { \n"
392 " gaussian = getGaussianFactor(i, tid, ki, 5.0); \n"
393 " n_x += gaussian * D_Normals[nearest_index * 3 + 0]; \n"
394 " n_y += gaussian * D_Normals[nearest_index * 3 + 1]; \n"
395 " n_z += gaussian * D_Normals[nearest_index * 3 + 2]; \n"
396 " } \n"
397 " } \n"
398 " } \n"
399 " if(tid < num_pointnormals-1) \n"
400 " { \n"
401 " for(unsigned int i = tid+1; i < num_pointnormals && c < ki; i++,c++ ) \n"
402 " { \n"
403 " nearest_index = (unsigned int)(D_kd_tree_values[i + offset]+ 0.5); \n"
404 " if(nearest_index < num_pointnormals) \n"
405 " { \n"
406 " gaussian = getGaussianFactor(i, tid, ki, 5.0); \n"
407 " n_x += gaussian * D_Normals[nearest_index * 3 + 0]; \n"
408 " n_y += gaussian * D_Normals[nearest_index * 3 + 1]; \n"
409 " n_z += gaussian * D_Normals[nearest_index * 3 + 2]; \n"
410 " } \n"
411 " } \n"
412 " } \n"
413 " float norm = sqrt(pow(n_x,2) + pow(n_y,2) + pow(n_z,2)); \n"
414 " n_x = n_x/norm; \n"
415 " n_y = n_y/norm; \n"
416 " n_z = n_z/norm; \n"
417 " D_Normals[query_index * 3 + 0] = n_x; \n"
418 " D_Normals[query_index * 3 + 1] = n_y; \n"
419 " D_Normals[query_index * 3 + 2] = n_z; \n"
420 " } \n"
421 " } \n"
422 "} \n";
423 
424 };
425 
426 } /* namespace lvr2 */
427 
428 #endif // !__ClSurface_H
void init()
PRIVATE ///.
Definition: ClSurface.cpp:235
void setKi(int ki)
Set the number of k nearest neighbors k-neighborhood for interpolation.
Definition: ClSurface.cpp:190
LBPointArray< unsigned char > * kd_tree_splits
Definition: ClSurface.hpp:161
void loadEstimationKernel()
Definition: ClSurface.cpp:296
void setKd(int kd)
Set the number of k nearest neighbors k-neighborhood for distance.
Definition: ClSurface.cpp:195
QueryPoint< Vec > QueryPointC
Definition: CudaSurface.hpp:75
LBPointArray< float > Result_Normals
Definition: ClSurface.hpp:163
LBPointArray< float > * kd_tree_values
Definition: ClSurface.hpp:160
cl_context m_context
Definition: ClSurface.hpp:180
LBPointArray< float > V
Definition: ClSurface.hpp:159
void calculateNormals()
Starts calculation the normals on GPU.
Definition: ClSurface.cpp:62
void setMethod(std::string method)
Set Method for normal calculation.
Definition: ClSurface.cpp:207
cl_kernel m_kernel_normal_interpolation
Definition: ClSurface.hpp:185
ClSurface(floatArr &points, size_t num_points, int device=0)
Definition: ClSurface.cpp:34
void setFlippoint(float v_x, float v_y, float v_z)
Set the viewpoint to orientate the normals.
Definition: ClSurface.cpp:200
A query Vector for marching cubes reconstructions. It represents a Vector in space together with a &#39;d...
Definition: QueryPoint.hpp:48
void distances(std::vector< QueryPoint< Vec > > &query_points, float voxel_size)
Definition: ClSurface.cpp:223
const char * NORMAL_INTERPOLATION_KERNEL_STRING
Definition: ClSurface.hpp:337
cl_mem D_kd_tree_values
Definition: ClSurface.hpp:188
void setKn(int kn)
Set the number of k nearest neighbors k-neighborhood.
Definition: ClSurface.cpp:185
boost::shared_array< float > floatArr
Definition: DataStruct.hpp:133
cl_program m_program_in
Definition: ClSurface.hpp:183
cl_kernel m_kernel_normal_estimation
Definition: ClSurface.hpp:184
cl_mem D_kd_tree_splits
Definition: ClSurface.hpp:189
cl_ulong m_device_global_memory
Definition: ClSurface.hpp:178
void getDeviceInformation(int platform_id=0, int device_id=0)
Definition: ClSurface.cpp:460
KF_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func="")
Error handler. All GPU functions from this subsystem call the function to report an error...
const char * getErrorString(cl_int error)
Definition: ClSurface.cpp:382
cl_command_queue m_command_queue
Definition: ClSurface.hpp:181
cl_uint m_threads_per_block
Definition: ClSurface.hpp:177
bool m_reconstruction_mode
Definition: ClSurface.hpp:171
const char * NORMAL_ESTIMATION_KERNEL_STRING
Definition: ClSurface.hpp:193
BaseVector< float > Vec
cl_device_id m_device_id
Definition: ClSurface.hpp:175
void loadInterpolationKernel()
Definition: ClSurface.cpp:340
cl_program m_program_es
Definition: ClSurface.hpp:182
boost::shared_ptr< LBKdTree > kd_tree_gen
Definition: ClSurface.hpp:164
void setReconstructionMode(bool mode=true)
Definition: ClSurface.cpp:218
void getNormals(floatArr output_normals)
Get the resulting normals of the normal calculation. After calling "start".
Definition: ClSurface.cpp:177
cl_platform_id m_platform_id
Definition: ClSurface.hpp:174


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:06