9template<
typename Traits>
10template<
typename Po
intUserContainer,
typename Converter>
11inline void KdTreeBase<Traits>::build(PointUserContainer&& points, Converter c)
13 IndexContainer ids(points.size());
14 std::iota(ids.begin(), ids.end(), 0);
15 this->buildWithSampling(std::forward<PointUserContainer>(points), std::move(ids), std::move(c));
18template<
typename Traits>
27template<
typename Traits>
31 return m_nodes.empty() && m_indices.empty();
33 if(m_nodes.empty() || m_indices.empty())
38 std::vector<bool> b(point_count(),
false);
39 for(IndexType idx : m_indices)
41 if(idx < 0 || point_count() <= idx || b[idx])
48 for(NodeIndexType n=0;n<node_count();++n)
50 const NodeType& node = m_nodes[n];
53 if(sample_count() <= node.leaf_start() || node.leaf_start()+node.leaf_size() > sample_count())
60 if(node.inner_split_dim() < 0 || DataPoint::Dim-1 < node.inner_split_dim())
64 if(node_count() <= node.inner_first_child_id() || node_count() <= node.inner_first_child_id()+1)
74template<
typename Traits>
75void KdTreeBase<Traits>::print(std::ostream& os,
bool verbose)
const
78 os <<
"\n MaxNodes: " << MAX_NODE_COUNT;
79 os <<
"\n MaxPoints: " << MAX_POINT_COUNT;
80 os <<
"\n MaxDepth: " << MAX_DEPTH;
81 os <<
"\n PointCount: " << point_count();
82 os <<
"\n SampleCount: " << sample_count();
83 os <<
"\n NodeCount: " << node_count();
90 os <<
"\n Samples: [";
91 static constexpr IndexType SAMPLES_PER_LINE = 10;
92 for (IndexType i = 0; i < sample_count(); ++i)
94 os << (i == 0 ?
"" :
",");
95 os << (i % SAMPLES_PER_LINE == 0 ?
"\n " :
" ");
100 for (NodeIndexType n = 0; n < node_count(); ++n)
102 const NodeType& node = m_nodes[n];
105 os <<
"\n - Type: Leaf";
106 os <<
"\n Start: " << node.leaf_start();
107 os <<
"\n Size: " << node.leaf_size();
111 os <<
"\n - Type: Inner";
112 os <<
"\n SplitDim: " << node.inner_split_dim();
113 os <<
"\n SplitValue: " << node.inner_split_value();
114 os <<
"\n FirstChild: " << node.inner_first_child_id();
119template<
typename Traits>
120template<
typename Po
intUserContainer,
typename IndexUserContainer,
typename Converter>
121inline void KdTreeBase<Traits>::buildWithSampling(PointUserContainer&& points,
122 IndexUserContainer sampling,
125 PONCA_DEBUG_ASSERT(points.size() <= MAX_POINT_COUNT);
129 c(std::forward<PointUserContainer>(points), m_points);
131 m_nodes = NodeContainer();
132 m_nodes.reserve(4 * point_count() / m_min_cell_size);
133 m_nodes.emplace_back();
135 m_indices = std::move(sampling);
137 this->build_rec(0, 0, sample_count(), 1);
139 PONCA_DEBUG_ASSERT(this->valid());
142template<
typename Traits>
143void KdTreeBase<Traits>::build_rec(NodeIndexType node_id, IndexType start, IndexType end,
int level)
145 NodeType& node = m_nodes[node_id];
147 for(IndexType i=start; i<end; ++i)
148 aabb.extend(m_points[m_indices[i]].pos());
151 end-start <= m_min_cell_size ||
152 level >= Traits::MAX_DEPTH ||
155 (NodeIndexType)m_nodes.size() > MAX_NODE_COUNT - 2);
157 node.configure_range(start, end-start, aabb);
165 (Scalar(0.5) * aabb.diagonal()).maxCoeff(&split_dim);
166 node.configure_inner(aabb.center()[split_dim], m_nodes.size(), split_dim);
167 m_nodes.emplace_back();
168 m_nodes.emplace_back();
170 IndexType mid_id = this->partition(start, end, split_dim, node.inner_split_value());
171 build_rec(node.inner_first_child_id(), start, mid_id, level+1);
172 build_rec(node.inner_first_child_id()+1, mid_id, end, level+1);
176template<
typename Traits>
180 const auto& points = m_points;
181 auto& indices = m_indices;
183 auto it = std::partition(indices.begin()+start, indices.begin()+end, [&](
IndexType i)
185 return points[i].pos()[dim] < value;
188 auto distance = std::distance(m_indices.begin(), it);
[KdTreeSparse type definition]
typename DataPoint::Scalar Scalar
Scalar given by user via DataPoint.
typename Traits::IndexType IndexType
Type used to index points into the PointContainer.
void clear()
Clear tree data.