51 typedef const std::vector< index_t >::iterator const_vector_itr;
53 template < index_t DIMENSION >
59 : bboxes_( bboxes ), coord_( coord )
63 bool operator()( index_t box1, index_t box2 )
65 return bboxes_[box1].center()[coord_]
66 < bboxes_[box2].center()[coord_];
70 const std::vector< Box< DIMENSION > >& bboxes_;
88 template <
class CMP >
89 const_vector_itr split(
90 const_vector_itr& begin, const_vector_itr& end, CMP cmp )
96 const_vector_itr middle = begin + ( end - begin ) / 2;
97 std::nth_element( begin, middle, end, cmp );
108 template < index_t DIMENSION >
111 template < index_t COORDX >
113 const_vector_itr& begin,
114 const_vector_itr& end );
117 std::vector< index_t >& mapping_morton )
119 sort< 0 >( bboxes, mapping_morton.begin(), mapping_morton.end() );
124 template < index_t COORDX >
125 void MortonSort< 3 >::sort(
const std::vector< Box3D >& bboxes,
126 const_vector_itr& begin,
127 const_vector_itr& end )
129 if( end - begin <= 1 )
133 const index_t COORDY = ( COORDX + 1 ) % 3, COORDZ = ( COORDY + 1 ) % 3;
135 const_vector_itr m0 = begin, m8 = end;
136 const_vector_itr m4 = split( m0, m8, Morton_cmp3D( bboxes, COORDX ) );
137 const_vector_itr m2 = split( m0, m4, Morton_cmp3D( bboxes, COORDY ) );
138 const_vector_itr m1 = split( m0, m2, Morton_cmp3D( bboxes, COORDZ ) );
139 const_vector_itr m3 = split( m2, m4, Morton_cmp3D( bboxes, COORDZ ) );
140 const_vector_itr m6 = split( m4, m8, Morton_cmp3D( bboxes, COORDY ) );
141 const_vector_itr m5 = split( m4, m6, Morton_cmp3D( bboxes, COORDZ ) );
142 const_vector_itr m7 = split( m6, m8, Morton_cmp3D( bboxes, COORDZ ) );
143 sort< COORDZ >( bboxes, m0, m1 );
144 sort< COORDY >( bboxes, m1, m2 );
145 sort< COORDY >( bboxes, m2, m3 );
146 sort< COORDX >( bboxes, m3, m4 );
147 sort< COORDX >( bboxes, m4, m5 );
148 sort< COORDY >( bboxes, m5, m6 );
149 sort< COORDY >( bboxes, m6, m7 );
150 sort< COORDZ >( bboxes, m7, m8 );
154 template < index_t COORDX >
155 void MortonSort< 2 >::sort(
const std::vector< Box2D >& bboxes,
156 const_vector_itr& begin,
157 const_vector_itr& end )
159 if( end - begin <= 1 )
163 const index_t COORDY = ( COORDX + 1 ) % 2;
165 const_vector_itr m0 = begin, m4 = end;
166 const_vector_itr m2 = split( m0, m4, Morton_cmp2D( bboxes, COORDX ) );
167 const_vector_itr m1 = split( m0, m2, Morton_cmp2D( bboxes, COORDY ) );
168 const_vector_itr m3 = split( m2, m4, Morton_cmp2D( bboxes, COORDY ) );
169 sort< COORDY >( bboxes, m0, m1 );
170 sort< COORDX >( bboxes, m1, m2 );
171 sort< COORDX >( bboxes, m2, m3 );
172 sort< COORDY >( bboxes, m3, m4 );
175 template < index_t DIMENSION >
177 std::vector< index_t >& mapping_morton )
179 mapping_morton.resize( bboxes.size() );
180 std::iota( mapping_morton.begin(), mapping_morton.end(), 0 );
181 MortonSort< DIMENSION >( bboxes, mapping_morton );
184 template < index_t DIMENSION >
210 template < index_t DIMENSION >
214 morton_sort( bboxes, mapping_morton_ );
215 index_t nb_bboxes =
static_cast< index_t
>( bboxes.size() );
216 tree_.resize( max_node_index( ROOT_INDEX, 0, nb_bboxes ) + ROOT_INDEX );
217 initialize_tree_recursive( bboxes, ROOT_INDEX, 0, nb_bboxes );
220 template < index_t DIMENSION >
222 index_t node_index, index_t box_begin, index_t box_end )
225 if( is_leaf( box_begin, box_end ) )
229 index_t element_middle, child_left, child_right;
230 get_recursive_iterators( node_index, box_begin, box_end, element_middle,
231 child_left, child_right );
233 max_node_index( child_left, box_begin, element_middle ),
234 max_node_index( child_right, element_middle, box_end ) );
245 template < index_t DIMENSION >
254 if( is_leaf( box_begin, box_end ) )
256 node( node_index ) = bboxes[mapping_morton_[box_begin]];
259 index_t element_middle, child_left, child_right;
260 get_recursive_iterators( node_index, box_begin, box_end, element_middle,
261 child_left, child_right );
264 initialize_tree_recursive(
265 bboxes, child_left, box_begin, element_middle );
266 initialize_tree_recursive(
267 bboxes, child_right, element_middle, box_end );
269 node( child_left ).bbox_union( node( child_right ) );
272 template < index_t DIMENSION >
273 std::tuple< index_t, vecn< DIMENSION >,
double >
277 index_t box_begin = 0;
278 index_t box_end = nb_bboxes();
279 index_t node_index = ROOT_INDEX;
280 while( !is_leaf( box_begin, box_end ) )
282 index_t box_middle, child_left, child_right;
283 get_recursive_iterators( node_index, box_begin, box_end, box_middle,
284 child_left, child_right );
285 if( length2( node( child_left ).center() - query )
286 < length2( node( child_right ).center() - query ) )
288 box_end = box_middle;
289 node_index = child_left;
293 box_begin = box_middle;
294 node_index = child_right;
298 index_t nearest_box = mapping_morton_[box_begin];
300 get_point_hint_from_box( tree_[box_begin], nearest_box );
301 double distance = length( query - nearest_point );
302 return std::make_tuple( nearest_box, nearest_point, distance );
307 template < index_t DIMENSION >
311 this->initialize_tree( bboxes );
314 template < index_t DIMENSION >
324 template < index_t DIMENSION >
328 std::vector< Box< DIMENSION > > bboxes;
332 for(
auto v :
range( 2 ) )
334 bboxes[i].add_point( mesh.
vertex(
341 template < index_t DIMENSION >
342 std::tuple< index_t, vecn< DIMENSION >,
double >
350 template < index_t DIMENSION >
351 std::tuple< double, vecn< DIMENSION > >
355 const auto& v0 =
mesh_.vertex(
mesh_.edge_vertex( { cur_box, 0 } ) );
356 const auto& v1 =
mesh_.vertex(
mesh_.edge_vertex( { cur_box, 1 } ) );
361 template < index_t DIMENSION >
372 template < index_t DIMENSION >
377 std::vector< Box< DIMENSION > > bboxes;
383 bboxes[i].add_point( mesh.
vertex(
390 template < index_t DIMENSION >
391 std::tuple< index_t, vecn< DIMENSION >,
double >
399 template < index_t DIMENSION >
400 std::tuple< double, vecn< DIMENSION > >
404 const auto& v0 =
mesh_.vertex(
mesh_.polygon_vertex( { cur_box, 0 } ) );
405 const auto& v1 =
mesh_.vertex(
mesh_.polygon_vertex( { cur_box, 1 } ) );
406 const auto& v2 =
mesh_.vertex(
mesh_.polygon_vertex( { cur_box, 2 } ) );
411 template < index_t DIMENSION >
422 template < index_t DIMENSION >
427 std::vector< Box< DIMENSION > > bboxes;
433 bboxes[i].add_point( mesh.
vertex(
440 template < index_t DIMENSION >
449 template < index_t DIMENSION >
457 template < index_t DIMENSION >
462 index_t box_end )
const 468 if( box_end == box_begin + 1 )
471 if( mesh_cell_contains_point(
mesh_, cell_id, query ) )
481 index_t box_middle, child_left, child_right;
483 box_middle, child_left, child_right );
486 query, child_left, box_begin, box_middle );
487 if( result == NO_ID )
490 query, child_right, box_middle, box_end );
494 template < index_t DIMENSION >
499 double result = std::abs( p[0] - B.
min()[0] );
500 result = std::min( result, std::abs( p[0] - B.
max()[0] ) );
501 for(
auto c :
range( 1, DIMENSION ) )
503 result = std::min( result, std::abs( p[c] - B.
min()[c] ) );
504 result = std::min( result, std::abs( p[c] - B.
max()[c] ) );
508 template < index_t DIMENSION >
514 for(
auto c :
range( DIMENSION ) )
516 if( p[c] < B.
min()[c] )
519 result[c] = p[c] - B.
min()[c];
521 else if( p[c] > B.
max()[c] )
524 result[c] = p[c] - B.
max()[c];
533 return result.length();
GEO::vecng< DIMENSION, double > vecn
std::tuple< index_t, vecn< DIMENSION >, double > closest_edge(const vecn< DIMENSION > &query) const
Gets the closest edge to a given point.
virtual index_t nb_cell_vertices(index_t cell_id) const =0
Gets the number of vertices of a cell.
virtual const vecn< DIMENSION > & vertex(index_t v_id) const =0
Gets a point.
double point_box_signed_distance(const vecn< DIMENSION > &p, const Box< DIMENSION > &B)
void get_recursive_iterators(index_t node_index, index_t box_begin, index_t box_end, index_t &middle_box, index_t &child_left, index_t &child_right) const
std::tuple< double, vecn< DIMENSION > > point_to_triangle(const Geometry::Point< DIMENSION > &point, const Geometry::Triangle< DIMENSION > &triangle)
bool contains(const vecn< DIMENSION > &b) const
std::vector< index_t > mapping_morton_
SurfaceAABBTree(const SurfaceMeshBase< DIMENSION > &mesh)
void ringmesh_unused(const T &)
virtual index_t cell_vertex(const ElementLocalVertex &cell_local_vertex) const =0
Gets a vertex index by cell and local vertex index.
const LineMesh< DIMENSION > & mesh_
index_t containing_cell_recursive(const vecn< DIMENSION > &query, index_t node_index, index_t box_begin, index_t box_end) const
const SurfaceMeshBase< DIMENSION > & mesh_
std::tuple< double, vecn< DIMENSION > > operator()(const vecn< DIMENSION > &query, index_t cur_box) const
virtual index_t nb_edges() const =0
Gets the number of all the edges in the whole Mesh.
vecn< DIMENSION > center() const
vecn< DIMENSION > get_point_hint_from_box(const Box< DIMENSION > &box, index_t element_id) const override
Gets an element point from its box.
virtual index_t polygon_vertex(const ElementLocalVertex &polygon_local_vertex) const =0
Gets the vertex index by polygon index and local vertex index.
std::tuple< index_t, vecn< DIMENSION >, double > get_nearest_element_box_hint(const vecn< DIMENSION > &query) const
Gets an hint of the result.
BoxAABBTree(const std::vector< Box< DIMENSION > > &boxes)
vecn< DIMENSION > get_point_hint_from_box(const Box< DIMENSION > &box, index_t element_id) const override
Gets an element point from its box.
vecn< DIMENSION > get_point_hint_from_box(const Box< DIMENSION > &box, index_t element_id) const override
Gets an element point from its box.
std::tuple< double, vecn< DIMENSION > > operator()(const vecn< DIMENSION > &query, index_t cur_box) const
double inner_point_box_distance(const vecn< DIMENSION > &p, const Box< DIMENSION > &B)
void initialize_tree_recursive(const std::vector< Box< DIMENSION > > &bboxes, index_t node_index, index_t element_begin, index_t element_end)
The recursive instruction used in initialize_tree()
const vecn< DIMENSION > & max() const
virtual CellType cell_type(index_t cell_id) const =0
Gets the type of a cell.
LineAABBTree(const LineMesh< DIMENSION > &mesh)
const VolumeMesh< DIMENSION > & mesh_
index_t max_node_index(index_t node_index, index_t box_begin, index_t box_end)
Gets the number of nodes in the tree subset.
virtual index_t nb_polygon_vertices(index_t polygon_id) const =0
Gets the number of vertices in the polygon.
VolumeAABBTree(const VolumeMesh< DIMENSION > &mesh)
const vecn< DIMENSION > & min() const
#define ringmesh_assert(x)
index_t containing_cell(const vecn< DIMENSION > &query) const
Gets the cell contining a point.
bool contains(const container &in, const T &value)
index_t nb_bboxes() const
virtual index_t nb_cells() const =0
Gets the number of cells in the Mesh.
virtual index_t nb_polygons() const =0
Gets the number of all polygons in the whole Mesh.
Classes to build GeoModel from various inputs.
vecn< DIMENSION > get_point_hint_from_box(const Box< DIMENSION > &box, index_t element_id) const override
Gets an element point from its box.
virtual index_t edge_vertex(const ElementLocalVertex &edge_local_vertex) const =0
std::tuple< index_t, vecn< DIMENSION >, double > closest_triangle(const vecn< DIMENSION > &query) const
Gets the closest triangle to a given point.
void initialize_tree(const std::vector< Box< DIMENSION > > &bboxes)
Builds the tree.
bool RINGMESH_API point_inside_tetra(const Geometry::Point3D &point, const Geometry::Tetra &tetra)
std::tuple< double, vecn< DIMENSION > > point_to_segment(const Geometry::Point< DIMENSION > &point, const Geometry::Segment< DIMENSION > &segment)
std::tuple< index_t, vecn< DIMENSION >, double > closest_element_box(const vecn< DIMENSION > &query, const EvalDistance &action) const
Gets the closest element box to a point.
const Box< DIMENSION > & node(index_t i) const
#define ringmesh_assert_not_reached