47 #include <geogram/points/kd_tree.h> 51 template < index_t DIMENSION >
56 : nn_tree_(
GEO::NearestNeighborSearch::create( DIMENSION,
"BNN" ) )
58 auto nb_vertices =
static_cast< index_t
>( vertices.size() );
61 nn_points_ =
new double[nb_vertices * DIMENSION];
62 delete_points_ =
true;
63 GEO::Memory::copy( nn_points_, vertices.data()->data(),
64 DIMENSION * nb_vertices *
sizeof(
double ) );
68 nn_points_ =
const_cast< double*
>( vertices.data()->data() );
69 delete_points_ =
false;
71 nn_tree_->set_points( nb_vertices, nn_points_ );
85 for(
auto i :
range( DIMENSION ) )
87 nn_points_[index_in_nn_search + i] = center[i];
94 for(
auto i :
range( DIMENSION ) )
96 result[i] = nn_points_[DIMENSION * v + i];
103 return nn_tree_->nb_points();
109 std::vector< index_t > result;
112 nb_neighbors = std::min( nb_neighbors,
nb_points() );
113 std::vector< double > distances( nb_neighbors );
114 result.resize( nb_neighbors );
115 nn_tree_->get_nearest_neighbors(
116 nb_neighbors, v.data(), &result[0], &distances[0] );
134 template < index_t DIMENSION >
137 : impl_( vertices, copy )
141 template < index_t DIMENSION >
144 return impl_->point( v );
147 template < index_t DIMENSION >
150 return impl_->nb_points();
153 template < index_t DIMENSION >
154 std::tuple< index_t, std::vector< index_t > >
156 double epsilon )
const 158 std::vector< index_t > index_map(
nb_points() );
159 std::atomic< index_t > nb_colocalised_vertices{ 0 };
161 &epsilon]( index_t i ) {
163 index_t
id{ *std::min_element( results.begin(), results.end() ) };
167 nb_colocalised_vertices++;
170 return std::make_tuple( nb_colocalised_vertices.load(), index_map );
173 template < index_t DIMENSION >
175 std::vector< index_t >,
176 std::vector< vecn< DIMENSION > > >
178 double epsilon )
const 180 index_t nb_colocalised_vertices;
181 std::vector< index_t > index_map;
182 std::tie( nb_colocalised_vertices, index_map ) =
184 std::vector< vecn< DIMENSION > > unique_points;
185 unique_points.reserve(
nb_points() - nb_colocalised_vertices );
187 for(
auto p :
range( index_map.size() ) )
189 if( index_map[p] == p )
191 unique_points.push_back(
point( p ) );
192 index_map[p] = p - offset;
197 index_map[p] = index_map[index_map[p]];
201 return std::make_tuple( offset, index_map, unique_points );
204 template < index_t DIMENSION >
208 double threshold_distance_sq{ threshold_distance * threshold_distance };
210 v, [
this, &v, threshold_distance_sq]( index_t i ) {
211 return length2( v -
point( i ) ) > threshold_distance_sq;
215 template < index_t DIMENSION >
219 return impl_->get_neighbors( v, nb_neighbors );
GEO::vecng< DIMENSION, double > vecn
index_t nb_points() const
Impl(const std::vector< vecn< DIMENSION > > &vertices, bool copy)
vecn< DIMENSION > point(index_t v) const
void fill_nn_search_points(index_t index_in_nn_search, const vecn< DIMENSION > ¢er)
bool delete_points_
Indicates if ann_points_ should be deleted.
GEO::NearestNeighborSearch_var nn_tree_
KdTree to compute the nearest neighbor search.
double * nn_points_
Array of the points (size of DIMENSIONxnumber of points)
template class RINGMESH_API EXPORT_IMPLEMENTATION(NNSearch< 2 >)
index_t nb_points() const
NNSearch(const std::vector< vecn< DIMENSION > > &vertices, bool copy=true)
#define ringmesh_assert(x)
vecn< DIMENSION > point(index_t v) const
std::vector< index_t > get_neighbors(const vecn< DIMENSION > &v, index_t nb_neighbors) const
Classes to build GeoModel from various inputs.
std::vector< index_t > get_neighbors(const vecn< DIMENSION > &v, double threshold_distance) const
std::tuple< index_t, std::vector< index_t > > get_colocated_index_mapping(double epsilon) const
Gets the index_map that link all the duplicated points to their first occurancy.
std::tuple< index_t, std::vector< index_t >, std::vector< vecn< DIMENSION > > > get_colocated_index_mapping_and_unique_points(double epsilon) const
Gets the index_map that link all the points to a no duplicated list of index in the list of unique_po...
void parallel_for(index_t size, const ACTION &action)