36 #include <boost/filesystem.hpp> 37 #include <boost/shared_array.hpp> 42 #define CL_HPP_TARGET_OPENCL_VERSION 120 43 #define CL_USE_DEPRECATED_OPENCL_1_2_APIS 44 #define __CL_ENABLE_EXCEPTIONS 46 #if defined(__APPLE__) || defined(__MACOSX) 47 #include <OpenCL/opencl.h> 53 #define MAX_SOURCE_SIZE (0x1024) 58 typedef boost::shared_array<float>
floatArr;
60 using Vec = BaseVector<float>;
65 ClSurface(floatArr& points,
size_t num_points,
int device = 0);
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" 198 " unsigned int pos = 0; \n" 199 " unsigned int current_dim = 0; \n" 200 " while(pos < num_splits) \n" 202 " current_dim = (unsigned int)(D_kd_tree_splits[pos]); \n" 203 " if(current_dim == 0) \n" 205 " if(x <= D_kd_tree_values[pos] ) \n" 211 " } else if(current_dim == 1) { \n" 212 " if(y <= D_kd_tree_values[pos] ){ \n" 218 " if(z <= D_kd_tree_values[pos] ){ \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" 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" 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" 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" 258 " correct = num_splits - start; \n" 259 " }else if(end > num_values) \n" 261 " correct = num_values - end; \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" 278 " nearest_index = (unsigned int)(D_kd_tree_values[i]+ 0.5); \n" 279 " if(nearest_index < num_points) \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" 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" 299 " if( det_x >= det_y && det_x >= det_z) \n" 302 " dir_y = (xz * yz - xy * zz) / det_x; \n" 303 " dir_z = (xy * yz - xz * yy) / det_x; \n" 305 " else if( det_y >= det_x && det_y >= det_z) \n" 307 " dir_x = (yz * xz - xy * zz) / det_y; \n" 309 " dir_z = (xy * xz - yz * xx) / det_y; \n" 312 " dir_x = (yz * xy - xz * yy ) / det_z; \n" 313 " dir_y = (xz * xy - yz * xx ) / det_z; \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" 326 " result_x = -result_x; \n" 327 " result_y = -result_y; \n" 328 " result_z = -result_z; \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" 338 "float getGaussianFactor(const unsigned int index, const unsigned int middle_i, " 339 "const unsigned int ki, const float norm) \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" 346 " val = val - middle; \n" 348 " val = middle - val; \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" 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" 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" 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" 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" 387 " for(unsigned int i = tid-1; i > 0 && c < ki/2; i--,c++ ) \n" 389 " nearest_index = (unsigned int)(D_kd_tree_values[i + offset]+ 0.5); \n" 390 " if(nearest_index < num_pointnormals) \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" 399 " if(tid < num_pointnormals-1) \n" 401 " for(unsigned int i = tid+1; i < num_pointnormals && c < ki; i++,c++ ) \n" 403 " nearest_index = (unsigned int)(D_kd_tree_values[i + offset]+ 0.5); \n" 404 " if(nearest_index < num_pointnormals) \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" 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" 428 #endif // !__ClSurface_H
void setKi(int ki)
Set the number of k nearest neighbors k-neighborhood for interpolation.
LBPointArray< unsigned char > * kd_tree_splits
void loadEstimationKernel()
void setKd(int kd)
Set the number of k nearest neighbors k-neighborhood for distance.
QueryPoint< Vec > QueryPointC
LBPointArray< float > Result_Normals
LBPointArray< float > * kd_tree_values
void calculateNormals()
Starts calculation the normals on GPU.
void setMethod(std::string method)
Set Method for normal calculation.
cl_kernel m_kernel_normal_interpolation
ClSurface(floatArr &points, size_t num_points, int device=0)
void setFlippoint(float v_x, float v_y, float v_z)
Set the viewpoint to orientate the normals.
A query Vector for marching cubes reconstructions. It represents a Vector in space together with a 'd...
void distances(std::vector< QueryPoint< Vec > > &query_points, float voxel_size)
const char * NORMAL_INTERPOLATION_KERNEL_STRING
void setKn(int kn)
Set the number of k nearest neighbors k-neighborhood.
boost::shared_array< float > floatArr
cl_kernel m_kernel_normal_estimation
cl_ulong m_device_global_memory
void getDeviceInformation(int platform_id=0, int device_id=0)
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)
cl_command_queue m_command_queue
cl_uint m_threads_per_block
bool m_reconstruction_mode
const char * NORMAL_ESTIMATION_KERNEL_STRING
void loadInterpolationKernel()
boost::shared_ptr< LBKdTree > kd_tree_gen
void setReconstructionMode(bool mode=true)
void getNormals(floatArr output_normals)
Get the resulting normals of the normal calculation. After calling "start".
cl_platform_id m_platform_id