Fermat
lbvh_builder_inline.h
1 /*
2  * Copyright (c) 2010-2018, NVIDIA Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of NVIDIA Corporation nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <cugar/radixtree/cuda/radixtree.h>
29 #include <cugar/bits/morton.h>
30 #include <cugar/basic/cuda/sort.h>
31 #include <thrust/transform.h>
32 
33 namespace cugar {
34 namespace cuda {
35 
36 namespace lbvh {
37 
38  template <typename integer>
39  struct Morton_bits {};
40 
41  template <>
42  struct Morton_bits<uint32> { static const uint32 value = 30u; };
43 
44  template <>
45  struct Morton_bits<uint64> { static const uint32 value = 60u; };
46 
47 };
48 
49 // build a Linear BVH given a set of points
50 template <
51  typename integer,
52  typename bvh_node_type,
53  typename node_vector,
54  typename range_vector,
55  typename index_vector>
56 template <typename Iterator>
58  const Bbox3f bbox,
59  const Iterator points_begin,
60  const Iterator points_end,
61  const uint32 max_leaf_size,
62  Stats* stats)
63 {
64  const uint32 n_points = uint32( points_end - points_begin );
65 
66  m_bbox = bbox;
67  need_space( m_codes, n_points );
68  need_space( *m_index, n_points );
69  need_space( m_temp_codes, n_points );
70  need_space( m_temp_index, n_points );
71 
72  cuda::Timer timer;
73  if (stats)
74  stats->morton_time.start();
75 
76  if (n_points > 0)
77  {
78  // compute the Morton code for each point
80  points_begin,
81  points_begin + n_points,
82  m_codes.begin(),
84 
85  // setup the point indices, from 0 to n_points-1
86  thrust::copy(
87  thrust::counting_iterator<uint32>(0),
88  thrust::counting_iterator<uint32>(0) + n_points,
89  m_index->begin() );
90  }
91 
92  if (stats)
93  {
94  stats->morton_time.stop();
95  stats->sorting_time.start();
96  }
97 
98  if (n_points > 1)
99  {
100  // sort the indices by Morton code
101  SortBuffers<integer*,uint32*> sort_buffers;
102  sort_buffers.keys[0] = raw_pointer( m_codes );
103  sort_buffers.keys[1] = raw_pointer( m_temp_codes );
104  sort_buffers.values[0] = raw_pointer( *m_index );
105  sort_buffers.values[1] = raw_pointer( m_temp_index );
106 
107  SortEnactor sort_enactor;
108  sort_enactor.sort( n_points, sort_buffers );
109 
110  // check whether we need to copy the sort results back in place
111  if (sort_buffers.selector)
112  {
113  thrust::copy( m_temp_codes.begin(), m_temp_codes.begin() + n_points, m_codes.begin() );
114  thrust::copy( m_temp_index.begin(), m_temp_index.begin() + n_points, m_index->begin() );
115  }
116  }
117 
118  if (stats)
119  {
120  stats->sorting_time.stop();
121  stats->build_time.start();
122  }
123 
124  // generate a kd-tree
126  tree_writer.set_nodes( m_nodes );
127  tree_writer.set_leaf_ranges( m_leaf_ranges );
128  tree_writer.set_leaf_pointers( m_leaf_pointers );
129  tree_writer.set_parents( m_parents );
130  tree_writer.set_skip_nodes( m_skip_nodes );
131  tree_writer.set_node_ranges( m_node_ranges );
132 
133  const uint32 bits = lbvh::Morton_bits<integer>::value;
134 
136  m_kd_context,
137  n_points,
138  raw_pointer( m_codes ),
139  bits,
140  max_leaf_size,
141  false,
142  true,
143  tree_writer );
144 
145  m_leaf_count = m_kd_context.m_leaves;
146  m_node_count = m_kd_context.m_nodes;
147 
148  if (stats)
149  stats->build_time.stop();
150 }
151 
152 } // namespace cuda
153 } // namespace cugar
Definition: timer.h:46
void transform(const uint32 n, const Iterator in, const Output out, const Functor functor)
Definition: primitives_inl.h:357
Defines some general purpose algorithms.
Definition: sort.h:103
Definition: lbvh_builder_inline.h:39
T * raw_pointer(thrust::device_vector< T, Alloc > &vec)
Definition: thrust_view.h:69
Define CUDA based sort primitives.
Definition: morton.h:160
void start()
Definition: timer.h:103
Definition: bintree_writer.h:177
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
void build(const Bbox3f bbox, const Iterator points_begin, const Iterator points_end, const uint32 max_leaf_size, Stats *stats=NULL)
Definition: lbvh_builder_inline.h:57
Definition: lbvh_builder.h:51
void generate_radix_tree(const uint32 n_codes, const Integer *codes, const uint32 bits, const uint32 max_leaf_size, const bool keep_singletons, const bool middle_splits, Tree_writer &tree)
Definition: radixtree_inline.h:381
void stop()
Definition: timer.h:110
Definition: sort.h:160