| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef FLANN_CUDA_KD_TREE_BUILDER_H_ |
| | #define FLANN_CUDA_KD_TREE_BUILDER_H_ |
| | #include <thrust/host_vector.h> |
| | #include <thrust/device_vector.h> |
| | #include <thrust/sort.h> |
| | #include <thrust/partition.h> |
| | #include <thrust/unique.h> |
| | #include <thrust/scan.h> |
| | #include <FLANN/util/cutil_math.h> |
| | #include <stdlib.h> |
| |
|
| | |
| |
|
| | namespace flann |
| | { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | namespace cuda |
| | { |
| | namespace kd_tree_builder_detail |
| | { |
| | |
| | |
| | struct SplitInfo |
| | { |
| | union { |
| | struct |
| | { |
| | |
| | int left; |
| | |
| | int right; |
| | }; |
| | struct |
| | { |
| | int split_dim; |
| | float split_val; |
| | }; |
| | }; |
| |
|
| | }; |
| |
|
| | struct IsEven |
| | { |
| | typedef int result_type; |
| | __device__ |
| | int operator()(int i ) |
| | { |
| | return (i& 1)==0; |
| | } |
| | }; |
| |
|
| | struct SecondElementIsEven |
| | { |
| | __host__ __device__ |
| | bool operator()( const thrust::tuple<int,int>& i ) |
| | { |
| | return (thrust::get<1>(i)& 1)==0; |
| | } |
| | }; |
| |
|
| | |
| | |
| | __host__ __device__ |
| | float get_value_by_index( const float4& f, int i ) |
| | { |
| | switch(i) { |
| | case 0: |
| | return f.x; |
| | case 1: |
| | return f.y; |
| | default: |
| | return f.z; |
| | } |
| |
|
| | } |
| |
|
| | |
| | |
| | struct MovePointsToChildNodes |
| | { |
| | MovePointsToChildNodes( int* child1, SplitInfo* splits, float* x, float* y, float* z, int* ox, int* oy, int* oz, int* lrx, int* lry, int* lrz ) |
| | : child1_(child1), splits_(splits), x_(x), y_(y), z_(z), ox_(ox), oy_(oy), oz_(oz), lrx_(lrx), lry_(lry), lrz_(lrz){} |
| | |
| | |
| | int* child1_; |
| | SplitInfo* splits_; |
| |
|
| | |
| | float* x_, * y_, * z_; |
| | |
| | int* ox_, * oy_, * oz_; |
| | |
| | |
| | int* lrx_, * lry_, * lrz_; |
| | __device__ |
| | void operator()( const thrust::tuple<int, int, int, int>& data ) |
| | { |
| | int index = thrust::get<0>(data); |
| | int owner = ox_[index]; |
| | int point_ind1=thrust::get<1>(data); |
| | int point_ind2=thrust::get<2>(data); |
| | int point_ind3=thrust::get<3>(data); |
| | int leftChild=child1_[owner]; |
| | int split_dim; |
| | float dim_val1, dim_val2, dim_val3; |
| | SplitInfo split; |
| | lrx_[index]=0; |
| | lry_[index]=0; |
| | lrz_[index]=0; |
| | |
| | if( leftChild==-1 ) { |
| | return; |
| | } |
| | |
| | split = splits_[owner]; |
| | split_dim=split.split_dim; |
| | switch( split_dim ) { |
| | case 0: |
| | dim_val1=x_[point_ind1]; |
| | dim_val2=x_[point_ind2]; |
| | dim_val3=x_[point_ind3]; |
| | break; |
| | case 1: |
| | dim_val1=y_[point_ind1]; |
| | dim_val2=y_[point_ind2]; |
| | dim_val3=y_[point_ind3]; |
| | break; |
| | default: |
| | dim_val1=z_[point_ind1]; |
| | dim_val2=z_[point_ind2]; |
| | dim_val3=z_[point_ind3]; |
| | break; |
| |
|
| | } |
| |
|
| |
|
| | int r1=leftChild +(dim_val1 > split.split_val); |
| | ox_[index]=r1; |
| | int r2=leftChild+(dim_val2 > split.split_val); |
| | oy_[index]=r2; |
| | oz_[index]=leftChild+(dim_val3 > split.split_val); |
| |
|
| | lrx_[index] = (dim_val1 > split.split_val); |
| | lry_[index] = (dim_val2 > split.split_val); |
| | lrz_[index] = (dim_val3 > split.split_val); |
| | |
| | } |
| | }; |
| |
|
| | |
| | struct SetLeftAndRightAndAABB |
| | { |
| | int maxPoints; |
| | int nElements; |
| |
|
| | SplitInfo* nodes; |
| | int* counts; |
| | int* labels; |
| | float4* aabbMin; |
| | float4* aabbMax; |
| | const float* x,* y,* z; |
| | const int* ix, * iy, * iz; |
| |
|
| | __host__ __device__ |
| | void operator()( int i ) |
| | { |
| | int index=labels[i]; |
| | int right; |
| | int left = counts[i]; |
| | nodes[index].left=left; |
| | if( i < nElements-1 ) { |
| | right=counts[i+1]; |
| | } |
| | else { |
| | right=maxPoints; |
| | } |
| | nodes[index].right=right; |
| | aabbMin[index].x=x[ix[left]]; |
| | aabbMin[index].y=y[iy[left]]; |
| | aabbMin[index].z=z[iz[left]]; |
| | aabbMax[index].x=x[ix[right-1]]; |
| | aabbMax[index].y=y[iy[right-1]]; |
| | aabbMax[index].z=z[iz[right-1]]; |
| | } |
| | }; |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | struct SplitNodes |
| | { |
| | int maxPointsPerNode; |
| | int* node_count; |
| | int* nodes_allocated; |
| | int* out_of_space; |
| | int* child1_; |
| | int* parent_; |
| | SplitInfo* splits; |
| |
|
| | __device__ |
| | void operator()( thrust::tuple<int&, int&,SplitInfo&,float4&,float4&, int> node ) |
| | { |
| | int& parent=thrust::get<0>(node); |
| | int& child1=thrust::get<1>(node); |
| | SplitInfo& s=thrust::get<2>(node); |
| | const float4& aabbMin=thrust::get<3>(node); |
| | const float4& aabbMax=thrust::get<4>(node); |
| | int my_index = thrust::get<5>(node); |
| | bool split_node=false; |
| | |
| | __shared__ int block_nodes_to_allocate; |
| | if( threadIdx.x== 0 ) block_nodes_to_allocate=0; |
| | __syncthreads(); |
| |
|
| | |
| | |
| | bool all_points_in_node_are_equal=aabbMin.x == aabbMax.x && aabbMin.y==aabbMax.y && aabbMin.z==aabbMax.z; |
| |
|
| | int offset_to_global=0; |
| |
|
| | |
| | if(( child1==-1) &&( s.right-s.left > maxPointsPerNode) && !all_points_in_node_are_equal ) { |
| | split_node=true; |
| | offset_to_global = atomicAdd( &block_nodes_to_allocate,2 ); |
| | } |
| |
|
| | __syncthreads(); |
| | __shared__ int block_left; |
| | __shared__ bool enough_space; |
| | |
| | if( threadIdx.x==0) { |
| | block_left = atomicAdd( node_count, block_nodes_to_allocate ); |
| | enough_space = block_left+block_nodes_to_allocate < *nodes_allocated; |
| | |
| | if( !enough_space ) { |
| | atomicAdd( node_count, -block_nodes_to_allocate ); |
| | *out_of_space=1; |
| | } |
| | } |
| |
|
| | __syncthreads(); |
| | |
| | |
| | |
| | |
| | |
| | if( split_node && enough_space ) { |
| | int left = block_left + offset_to_global; |
| |
|
| | splits[left].left=s.left; |
| | splits[left].right=s.right; |
| | splits[left+1].left=0; |
| | splits[left+1].right=0; |
| |
|
| | |
| | float4 aabbDim=aabbMax-aabbMin; |
| | int maxDim=0; |
| | float maxDimLength=aabbDim.x; |
| | float4 splitVal=(aabbMax+aabbMin); |
| | splitVal*=0.5f; |
| | for( int i=1; i<=2; i++ ) { |
| | float val = get_value_by_index(aabbDim,i); |
| | if( val > maxDimLength ) { |
| | maxDim=i; |
| | maxDimLength=val; |
| | } |
| | } |
| | s.split_dim=maxDim; |
| | s.split_val=get_value_by_index(splitVal,maxDim); |
| |
|
| | child1_[my_index]=left; |
| | splits[my_index]=s; |
| |
|
| | parent_[left]=my_index; |
| | parent_[left+1]=my_index; |
| | child1_[left]=-1; |
| | child1_[left+1]=-1; |
| | } |
| | } |
| | }; |
| |
|
| |
|
| | |
| | |
| | struct set_addr3 |
| | { |
| | const int* val_, * f_; |
| |
|
| | int npoints_; |
| | __device__ |
| | int operator()( int id ) |
| | { |
| | int nf = f_[npoints_-1] + (val_[npoints_-1]); |
| | int f=f_[id]; |
| | int t = id -f+nf; |
| | return val_[id] ? f : t; |
| | } |
| | }; |
| |
|
| | |
| | |
| | struct pointxyz_to_px_py_pz |
| | { |
| | __device__ |
| | thrust::tuple<float,float,float> operator()( const float4& val ) |
| | { |
| | return thrust::make_tuple(val.x, val.y, val.z); |
| | } |
| | }; |
| | } |
| |
|
| | } |
| |
|
| |
|
| | std::ostream& operator <<(std::ostream& stream, const cuda::kd_tree_builder_detail::SplitInfo& s) |
| | { |
| | stream<<"(split l/r: "<< s.left <<" "<< s.right<< " split:"<<s.split_dim<<" "<<s.split_val<<")"; |
| | return stream; |
| | } |
| | class CudaKdTreeBuilder |
| | { |
| | public: |
| | CudaKdTreeBuilder( const thrust::device_vector<float4>& points, int max_leaf_size ) : max_leaf_size_(max_leaf_size) |
| | { |
| | points_=&points; |
| | int prealloc = points.size()/max_leaf_size_*16; |
| | allocation_info_.resize(3); |
| | allocation_info_[NodeCount]=1; |
| | allocation_info_[NodesAllocated]=prealloc; |
| | allocation_info_[OutOfSpace]=0; |
| |
|
| | |
| |
|
| | child1_=new thrust::device_vector<int>(prealloc,-1); |
| | parent_=new thrust::device_vector<int>(prealloc,-1); |
| | cuda::kd_tree_builder_detail::SplitInfo s; |
| | s.left=0; |
| | s.right=0; |
| | splits_=new thrust::device_vector<cuda::kd_tree_builder_detail::SplitInfo>(prealloc,s); |
| | s.right=points.size(); |
| | (*splits_)[0]=s; |
| |
|
| | aabb_min_=new thrust::device_vector<float4>(prealloc); |
| | aabb_max_=new thrust::device_vector<float4>(prealloc); |
| |
|
| | index_x_=new thrust::device_vector<int>(points_->size()); |
| | index_y_=new thrust::device_vector<int>(points_->size()); |
| | index_z_=new thrust::device_vector<int>(points_->size()); |
| |
|
| | owners_x_=new thrust::device_vector<int>(points_->size(),0); |
| | owners_y_=new thrust::device_vector<int>(points_->size(),0); |
| | owners_z_=new thrust::device_vector<int>(points_->size(),0); |
| |
|
| | leftright_x_ = new thrust::device_vector<int>(points_->size(),0); |
| | leftright_y_ = new thrust::device_vector<int>(points_->size(),0); |
| | leftright_z_ = new thrust::device_vector<int>(points_->size(),0); |
| |
|
| | tmp_index_=new thrust::device_vector<int>(points_->size()); |
| | tmp_owners_=new thrust::device_vector<int>(points_->size()); |
| | tmp_misc_=new thrust::device_vector<int>(points_->size()); |
| |
|
| | points_x_=new thrust::device_vector<float>(points_->size()); |
| | points_y_=new thrust::device_vector<float>(points_->size()); |
| | points_z_=new thrust::device_vector<float>(points_->size()); |
| | delete_node_info_=false; |
| | } |
| |
|
| | ~CudaKdTreeBuilder() |
| | { |
| | if( delete_node_info_ ) { |
| | delete child1_; |
| | delete parent_; |
| | delete splits_; |
| | delete aabb_min_; |
| | delete aabb_max_; |
| | delete index_x_; |
| | } |
| |
|
| | delete index_y_; |
| | delete index_z_; |
| | delete owners_x_; |
| | delete owners_y_; |
| | delete owners_z_; |
| | delete points_x_; |
| | delete points_y_; |
| | delete points_z_; |
| | delete leftright_x_; |
| | delete leftright_y_; |
| | delete leftright_z_; |
| | delete tmp_index_; |
| | delete tmp_owners_; |
| | delete tmp_misc_; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | void buildTree() |
| | { |
| | |
| | |
| | |
| | thrust::transform( points_->begin(), points_->end(), thrust::make_zip_iterator(thrust::make_tuple(points_x_->begin(), points_y_->begin(),points_z_->begin()) ), cuda::kd_tree_builder_detail::pointxyz_to_px_py_pz() ); |
| |
|
| | thrust::counting_iterator<int> it(0); |
| | thrust::copy( it, it+points_->size(), index_x_->begin() ); |
| |
|
| | thrust::copy( index_x_->begin(), index_x_->end(), index_y_->begin() ); |
| | thrust::copy( index_x_->begin(), index_x_->end(), index_z_->begin() ); |
| |
|
| | thrust::device_vector<float> tmpv(points_->size()); |
| |
|
| | |
| | thrust::copy(points_x_->begin(), points_x_->end(), tmpv.begin()); |
| | thrust::sort_by_key( tmpv.begin(), tmpv.end(), index_x_->begin() ); |
| | thrust::copy(points_y_->begin(), points_y_->end(), tmpv.begin()); |
| | thrust::sort_by_key( tmpv.begin(), tmpv.end(), index_y_->begin() ); |
| | thrust::copy(points_z_->begin(), points_z_->end(), tmpv.begin()); |
| | thrust::sort_by_key( tmpv.begin(), tmpv.end(), index_z_->begin() ); |
| |
|
| |
|
| | (*aabb_min_)[0]=make_float4((*points_x_)[(*index_x_)[0]],(*points_y_)[(*index_y_)[0]],(*points_z_)[(*index_z_)[0]],0); |
| |
|
| | (*aabb_max_)[0]=make_float4((*points_x_)[(*index_x_)[points_->size()-1]],(*points_y_)[(*index_y_)[points_->size()-1]],(*points_z_)[(*index_z_)[points_->size()-1]],0); |
| | #ifdef PRINT_DEBUG_TIMING |
| | cudaDeviceSynchronize(); |
| | std::cout<<" initial stuff:"<<stepTimer.elapsed()<<std::endl; |
| | stepTimer.restart(); |
| | #endif |
| | int last_node_count=0; |
| | for( int i=0;; i++ ) { |
| | cuda::kd_tree_builder_detail::SplitNodes sn; |
| |
|
| | sn.maxPointsPerNode=max_leaf_size_; |
| | sn.node_count=thrust::raw_pointer_cast(&allocation_info_[NodeCount]); |
| | sn.nodes_allocated=thrust::raw_pointer_cast(&allocation_info_[NodesAllocated]); |
| | sn.out_of_space=thrust::raw_pointer_cast(&allocation_info_[OutOfSpace]); |
| | sn.child1_=thrust::raw_pointer_cast(&(*child1_)[0]); |
| | sn.parent_=thrust::raw_pointer_cast(&(*parent_)[0]); |
| | sn.splits=thrust::raw_pointer_cast(&(*splits_)[0]); |
| |
|
| | thrust::counting_iterator<int> cit(0); |
| | thrust::for_each( thrust::make_zip_iterator(thrust::make_tuple( parent_->begin(), child1_->begin(), splits_->begin(), aabb_min_->begin(), aabb_max_->begin(), cit )), |
| | thrust::make_zip_iterator(thrust::make_tuple( parent_->begin()+last_node_count, child1_->begin()+last_node_count,splits_->begin()+last_node_count, aabb_min_->begin()+last_node_count, aabb_max_->begin()+last_node_count,cit+last_node_count )), |
| | sn ); |
| | |
| | thrust::host_vector<int> alloc_info = allocation_info_; |
| |
|
| | if( last_node_count == alloc_info[NodeCount] ) { |
| | break; |
| | } |
| | last_node_count=alloc_info[NodeCount]; |
| |
|
| | |
| | if( alloc_info[OutOfSpace]==1 ) { |
| | resize_node_vectors(alloc_info[NodesAllocated]*2); |
| | alloc_info[OutOfSpace]=0; |
| | alloc_info[NodesAllocated]*=2; |
| | allocation_info_=alloc_info; |
| | } |
| | #ifdef PRINT_DEBUG_TIMING |
| | cudaDeviceSynchronize(); |
| | std::cout<<" node split:"<<stepTimer.elapsed()<<std::endl; |
| | stepTimer.restart(); |
| | #endif |
| |
|
| | |
| | cuda::kd_tree_builder_detail::MovePointsToChildNodes sno( thrust::raw_pointer_cast(&(*child1_)[0]), |
| | thrust::raw_pointer_cast(&(*splits_)[0]), |
| | thrust::raw_pointer_cast(&(*points_x_)[0]), |
| | thrust::raw_pointer_cast(&(*points_y_)[0]), |
| | thrust::raw_pointer_cast(&(*points_z_)[0]), |
| | thrust::raw_pointer_cast(&(*owners_x_)[0]), |
| | thrust::raw_pointer_cast(&(*owners_y_)[0]), |
| | thrust::raw_pointer_cast(&(*owners_z_)[0]), |
| | thrust::raw_pointer_cast(&(*leftright_x_)[0]), |
| | thrust::raw_pointer_cast(&(*leftright_y_)[0]), |
| | thrust::raw_pointer_cast(&(*leftright_z_)[0]) |
| | ); |
| | thrust::counting_iterator<int> ci0(0); |
| | thrust::for_each( thrust::make_zip_iterator( thrust::make_tuple( ci0, index_x_->begin(), index_y_->begin(), index_z_->begin()) ), |
| | thrust::make_zip_iterator( thrust::make_tuple( ci0+points_->size(), index_x_->end(), index_y_->end(), index_z_->end()) ),sno ); |
| |
|
| | #ifdef PRINT_DEBUG_TIMING |
| | cudaDeviceSynchronize(); |
| | std::cout<<" set new owners:"<<stepTimer.elapsed()<<std::endl; |
| | stepTimer.restart(); |
| | #endif |
| |
|
| | |
| | separate_left_and_right_children(*index_x_,*owners_x_,*tmp_index_,*tmp_owners_, *leftright_x_); |
| | std::swap(tmp_index_, index_x_); |
| | std::swap(tmp_owners_, owners_x_); |
| | separate_left_and_right_children(*index_y_,*owners_y_,*tmp_index_,*tmp_owners_, *leftright_y_,false); |
| | std::swap(tmp_index_, index_y_); |
| | separate_left_and_right_children(*index_z_,*owners_z_,*tmp_index_,*tmp_owners_, *leftright_z_,false); |
| | std::swap(tmp_index_, index_z_); |
| |
|
| | #ifdef PRINT_DEBUG_TIMING |
| | cudaDeviceSynchronize(); |
| | std::cout<<" split:"<<stepTimer.elapsed()<<std::endl; |
| | stepTimer.restart(); |
| | #endif |
| | |
| | update_leftright_and_aabb( *points_x_, *points_y_, *points_z_, *index_x_, *index_y_, *index_z_, *owners_x_, *splits_,*aabb_min_, *aabb_max_); |
| | #ifdef PRINT_DEBUG_TIMING |
| | cudaDeviceSynchronize(); |
| | std::cout<<" update_leftright_and_aabb:"<<stepTimer.elapsed()<<std::endl; |
| | stepTimer.restart(); |
| | print_vector(node_count_); |
| | #endif |
| |
|
| | } |
| | } |
| |
|
| | template<class Distance> |
| | friend class KDTreeCuda3dIndex; |
| |
|
| | protected: |
| |
|
| |
|
| | |
| | void |
| | update_leftright_and_aabb( const thrust::device_vector<float>& x, const thrust::device_vector<float>& y,const thrust::device_vector<float>& z, |
| | const thrust::device_vector<int>& ix, const thrust::device_vector<int>& iy,const thrust::device_vector<int>& iz, |
| | const thrust::device_vector<int>& owners, |
| | thrust::device_vector<cuda::kd_tree_builder_detail::SplitInfo>& splits, thrust::device_vector<float4>& aabbMin,thrust::device_vector<float4>& aabbMax) |
| | { |
| | thrust::device_vector<int>* labelsUnique=tmp_owners_; |
| | thrust::device_vector<int>* countsUnique=tmp_index_; |
| | |
| |
|
| | |
| | int unique_labels = thrust::unique_by_key_copy( owners.begin(), owners.end(), thrust::counting_iterator<int>(0), labelsUnique->begin(), countsUnique->begin()).first - labelsUnique->begin(); |
| |
|
| | |
| | cuda::kd_tree_builder_detail::SetLeftAndRightAndAABB s; |
| | s.maxPoints=x.size(); |
| | s.nElements=unique_labels; |
| | s.nodes=thrust::raw_pointer_cast(&(splits[0])); |
| | s.counts=thrust::raw_pointer_cast(&( (*countsUnique)[0])); |
| | s.labels=thrust::raw_pointer_cast(&( (*labelsUnique)[0])); |
| | s.x=thrust::raw_pointer_cast(&x[0]); |
| | s.y=thrust::raw_pointer_cast(&y[0]); |
| | s.z=thrust::raw_pointer_cast(&z[0]); |
| | s.ix=thrust::raw_pointer_cast(&ix[0]); |
| | s.iy=thrust::raw_pointer_cast(&iy[0]); |
| | s.iz=thrust::raw_pointer_cast(&iz[0]); |
| | s.aabbMin=thrust::raw_pointer_cast(&aabbMin[0]); |
| | s.aabbMax=thrust::raw_pointer_cast(&aabbMax[0]); |
| |
|
| | thrust::counting_iterator<int> it(0); |
| | thrust::for_each(it, it+unique_labels, s); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | void separate_left_and_right_children( thrust::device_vector<int>& key_in, thrust::device_vector<int>& val_in, thrust::device_vector<int>& key_out, thrust::device_vector<int>& val_out, thrust::device_vector<int>& left_right_marks, bool scatter_val_out=true ) |
| | { |
| | thrust::device_vector<int>* f_tmp = &val_out; |
| | thrust::device_vector<int>* addr_tmp = tmp_misc_; |
| |
|
| | thrust::exclusive_scan( left_right_marks.begin() |
| | , left_right_marks.end() |
| | , f_tmp->begin() ); |
| | cuda::kd_tree_builder_detail::set_addr3 sa; |
| | sa.val_=thrust::raw_pointer_cast(&left_right_marks[0]); |
| | sa.f_=thrust::raw_pointer_cast(&(*f_tmp)[0]); |
| | sa.npoints_=key_in.size(); |
| | thrust::counting_iterator<int> it(0); |
| | thrust::transform(it, it+val_in.size(), addr_tmp->begin(), sa); |
| |
|
| | thrust::scatter(key_in.begin(), key_in.end(), addr_tmp->begin(), key_out.begin()); |
| | if( scatter_val_out ) thrust::scatter(val_in.begin(), val_in.end(), addr_tmp->begin(), val_out.begin()); |
| | } |
| |
|
| | |
| | |
| | void resize_node_vectors( size_t new_size ) |
| | { |
| | size_t add = new_size - child1_->size(); |
| | child1_->insert(child1_->end(), add, -1); |
| | parent_->insert(parent_->end(), add, -1); |
| | cuda::kd_tree_builder_detail::SplitInfo s; |
| | s.left=0; |
| | s.right=0; |
| | splits_->insert(splits_->end(), add, s); |
| | float4 f; |
| | aabb_min_->insert(aabb_min_->end(), add, f); |
| | aabb_max_->insert(aabb_max_->end(), add, f); |
| | } |
| |
|
| |
|
| | const thrust::device_vector<float4>* points_; |
| |
|
| | |
| |
|
| | |
| | |
| | thrust::device_vector<int>* child1_; |
| | |
| | thrust::device_vector<int>* parent_; |
| | |
| | thrust::device_vector<cuda::kd_tree_builder_detail::SplitInfo>* splits_; |
| | |
| | thrust::device_vector<float4>* aabb_min_; |
| | |
| | thrust::device_vector<float4>* aabb_max_; |
| |
|
| | enum AllocationInfo |
| | { |
| | NodeCount=0, |
| | NodesAllocated=1, |
| | OutOfSpace=2 |
| | }; |
| | |
| | |
| | |
| | |
| | thrust::device_vector<int> allocation_info_; |
| |
|
| | int max_leaf_size_; |
| |
|
| | |
| | thrust::device_vector<float>* points_x_, * points_y_, * points_z_; |
| | |
| | thrust::device_vector<int>* index_x_, * index_y_, * index_z_; |
| | |
| | thrust::device_vector<int>* owners_x_, * owners_y_, * owners_z_; |
| | |
| | thrust::device_vector<int>* leftright_x_, * leftright_y_, * leftright_z_; |
| | thrust::device_vector<int>* tmp_index_, * tmp_owners_, * tmp_misc_; |
| | bool delete_node_info_; |
| | }; |
| |
|
| |
|
| | } |
| | #endif |