40#ifndef GEOGRAM_MESH_MESH_AABB
41#define GEOGRAM_MESH_MESH_AABB
64 AABB_INPLACE, AABB_INDIRECT, AABB_NOREORDER
71 template <
class BOX>
class AABB {
80 for(
auto& B: bboxes_) {
121 std::function<
void(
index_t)> action,
const BOX& box,
192 if(b1 + 1 == e1 && b2 + 1 == e2) {
203 if(e2 - b2 > e1 - b1) {
204 index_t m2 = b2 + (e2 - b2) / 2;
206 index_t node2_r = 2 * node2 + 1;
210 index_t m1 = b1 + (e1 - b1) / 2;
212 index_t node1_r = 2 * node1 + 1;
255 if(b1 + 1 == e1 && b2 + 1 == e2) {
264 if(e2 - b2 > e1 - b1) {
265 index_t m2 = b2 + (e2 - b2) / 2;
267 index_t node2_r = 2 * node2 + 1;
269 action, node1, b1, e1, other, node2_l, b2, m2
272 action, node1, b1, e1, other, node2_r, m2, e2
275 index_t m1 = b1 + (e1 - b1) / 2;
277 index_t node1_r = 2 * node1 + 1;
279 action, node1_l, b1, m1, other, node2, b2, e2
282 action, node1_r, m1, e1, other, node2, b2, e2
301 index_t childl = 2 * node_index;
302 index_t childr = 2 * node_index + 1;
331 index_t childl = 2 * node_index;
332 index_t childr = 2 * node_index + 1;
339 bbox_union(bboxes_[node_index], bboxes_[childl], bboxes_[childr]);
441 t(Numeric::max_float64()),
443 i(NO_INDEX), j(NO_INDEX), k(NO_INDEX)
476 initialize(M, reorder_mode);
485 initialize(
const_cast<Mesh&
>(M), AABB_INDIRECT);
504 [[deprecated(
"use MeshFacetsAABB(Mesh&,AABBReorderMode) instead")]]
506 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
509 [[deprecated(
"use initialize(Mesh&,AABBReorderMode) instead")]]
510 void initialize(
Mesh& M,
bool reorder) {
511 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
527 bool concurrent =
false
530 Process::maximum_concurrent_threads() <= 1 ||
531 mesh_->facets.nb() <= 1024
533 self_intersect_recursive(
535 1, 0, mesh_->facets.nb(),
536 1, 0, mesh_->facets.nb()
539 self_bbox_intersections_parallel(action, concurrent);
552 const Box& box_in, std::function<
void(
index_t)> action
554 bbox_intersect_recursive(
555 action, box_in, 1, 0, mesh_->facets.nb()
569 const vec3& p,
vec3& nearest_point,
double& sq_dist
571 if(mesh_->facets.nb() == 0) {
572 sq_dist = Numeric::max_float64();
576 get_nearest_facet_hint(p, nearest_facet, nearest_point, sq_dist);
577 nearest_facet_recursive(
579 nearest_facet, nearest_point, sq_dist,
580 1, 0, mesh_->facets.nb()
582 return nearest_facet;
594 return nearest_facet(p, nearest_point, sq_dist);
610 const vec3& p,
vec3& nearest_point,
double& sq_dist,
611 std::function<
bool(
index_t)> filter
613 if(mesh_->facets.nb() == 0) {
616 index_t nearest_facet = NO_INDEX;
617 sq_dist = Numeric::max_float64();
618 nearest_facet_recursive_filtered(
620 nearest_facet, nearest_point, sq_dist,
621 1, 0, mesh_->facets.nb(),
624 return nearest_facet;
648 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist
650 if(mesh_->facets.nb() == 0) {
651 nearest_facet = NO_INDEX;
652 sq_dist = Numeric::max_float64();
653 nearest_point=
vec3(0,0,0);
656 if(nearest_facet == NO_FACET) {
657 get_nearest_facet_hint(
658 p, nearest_facet, nearest_point, sq_dist
661 nearest_facet_recursive(
663 nearest_facet, nearest_point, sq_dist,
664 1, 0, mesh_->facets.nb()
677 nearest_facet(p, nearest_point, result);
694 double tmax = Numeric::max_float64(),
719 return ray_intersection(
Ray(q1, q2-q1), 1.0);
739 bool result = ray_nearest_intersection(R,I);
795 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist
817 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist,
840 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist,
842 std::function<
bool(
index_t)> filter
899 const Ray& R,
const vec3& dirinv,
936 std::function<
void(
index_t,
index_t)> action,
bool concurrent=
false
976 initialize(M, reorder_mode);
985 initialize(
const_cast<Mesh&
>(M), AABB_INDIRECT);
1002 [[deprecated(
"use MeshCellsAABB(Mesh&,AABBReorderMode) instead")]]
1004 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
1007 [[deprecated(
"use initialize(Mesh&,AABBReorderMode) instead")]]
1008 void initialize(
Mesh& M,
bool reorder) {
1009 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
1023 return containing_tet_recursive(
1024 p, 1, 0, mesh_->cells.nb()
1037 std::function<
void(
index_t)> action
1039 bbox_intersect_recursive(
1040 action, box_in, 1, 0, mesh_->cells.nb()
1052 const vec3& p, std::function<
void(
index_t)> action
1054 containing_bboxes_recursive(
1055 action, p, 1, 0, mesh_->cells.nb()
1069 self_intersect_recursive(
1071 1, 0, mesh_->cells.nb(),
1072 1, 0, mesh_->cells.nb()
1089 other_intersect_recursive(
1091 1, 0, mesh_->cells.nb(),
1093 1, 0, other->mesh_->cells.
nb()
1136 std::function<
void(
index_t)> action,
1143 if(!bboxes_[node].contains(p)) {
1149 action(element_in_leaf(b));
1156 index_t node_r = 2 * node + 1;
1158 containing_bboxes_recursive(action, p, node_l, b, m);
1159 containing_bboxes_recursive(action, p, node_r, m, e);
1216 return containing_triangle_recursive(
1217 p, 1, 0, mesh_->facets.nb()
1229 const Box2d& box_in,
1230 std::function<
void(
index_t)> action
1232 bbox_intersect_recursive(
1233 action, box_in, 1, 0, mesh_->facets.nb()
1245 const vec2& p, std::function<
void(
index_t)> action
1247 containing_bboxes_recursive(
1248 action, p, 1, 0, mesh_->facets.nb()
1262 self_intersect_recursive(
1264 1, 0, mesh_->facets.nb(),
1265 1, 0, mesh_->facets.nb()
1282 other_intersect_recursive(
1284 1, 0, mesh_->facets.nb(),
1286 1, 0, other->mesh_->facets.
nb()
1329 std::function<
void(
index_t)> action,
1336 if(!bboxes_[node].contains(p)) {
1342 action(element_in_leaf(b));
1349 index_t node_r = 2 * node + 1;
1351 containing_bboxes_recursive(action, p, node_l, b, m);
1352 containing_bboxes_recursive(action, p, node_r, m, e);
#define geo_debug_assert(x)
Verifies that a condition is met.
Base class for Axis Aligned Bounding Box trees.
bool indirect() const
Tests whether this AABB is indirect or in-place.
void bbox_intersect_recursive(std::function< void(index_t)> action, const BOX &box, index_t node, index_t b, index_t e) const
Computes all the elements that have a bbox that intersects a given bbox in a sub-tree of the AABB tre...
void enlarge_boxes(double amount)
Enlarges all the boxes.
void self_intersect_recursive(std::function< void(index_t, index_t)> action, index_t node1, index_t b1, index_t e1, index_t node2, index_t b2, index_t e2) const
Computes all the pairs of intersecting elements for two sub-trees of the AABB tree.
void other_intersect_recursive(std::function< void(index_t, index_t)> action, index_t node1, index_t b1, index_t e1, const AABB< BOX > *other, index_t node2, index_t b2, index_t e2) const
Computes all the pairs of intersecting elements for two sub-trees of two AABB trees.
static index_t max_node_index(index_t node_index, index_t b, index_t e)
Computes the maximum node index in a subtree.
vector< index_t > reorder_
void initialize(index_t nb, std::function< void(BOX &, index_t)> get_bbox)
Initializes this AABB.
void init_bboxes_recursive(index_t node_index, index_t b, index_t e, std::function< void(BOX &, index_t)> get_bbox)
Computes the hierarchy of bounding boxes recursively.
index_t element_in_leaf(index_t i) const
Gets the element stored in a leaf node.
Axis-aligned bounding box.
Axis-aligned bounding box.
Base class for Axis Aligned Bounding Box trees of mesh elements with 2d boxes.
const Mesh * mesh() const
Gets the mesh.
MeshAABB2d()
MeshAABB2d constructor.
Base class for Axis Aligned Bounding Box trees of mesh elements with 3d boxes.
const Mesh * mesh() const
Gets the mesh.
MeshAABB3d()
MeshAABB3d constructor.
Axis Aligned Bounding Box tree of mesh cells.
void compute_cell_bbox_intersections(std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting cells.
void containing_boxes(const vec3 &p, std::function< void(index_t)> action) const
Finds all the cells such that their bounding box contain a point.
MeshCellsAABB()
MeshCellsAABB constructor.
index_t containing_tet_recursive(const vec3 &p, index_t n, index_t b, index_t e) const
The recursive function used by the implementation of containing_tet().
index_t containing_tet(const vec3 &p) const
Finds the index of a tetrahedron that contains a query point.
void compute_bbox_cell_bbox_intersections(const Box &box_in, std::function< void(index_t)> action) const
Computes all the intersections between a given box and the bounding boxes of all the cells.
void containing_bboxes_recursive(std::function< void(index_t)> action, const vec3 &p, index_t node, index_t b, index_t e) const
Computes all the cells that have a bbox that contain a given point in a sub-tree of the AABB tree.
MeshCellsAABB(Mesh &M, AABBReorderMode reorder_mode)
Creates an Axis Aligned Bounding Boxes tree for mesh cells.
void compute_other_cell_bbox_intersections(MeshCellsAABB *other, std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting cells between this AABB and another one.
MeshCellsAABB(const Mesh &M)
Creates an Axis Aligned Bounding Boxes tree for mesh cells.
void initialize(Mesh &M, AABBReorderMode reorder_mode=AABB_INDIRECT)
Initializes the Axis Aligned Bounding Boxes tree.
Axis Aligned Bounding Box tree of mesh facets in 2D.
void compute_facet_bbox_intersections(std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting facets.
void compute_other_cell_bbox_intersections(MeshFacetsAABB2d *other, std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting cells between this AABB and another one.
index_t containing_triangle_recursive(const vec2 &p, index_t n, index_t b, index_t e) const
The recursive function used by the implementation of containing_triangle().
MeshFacetsAABB2d()
MeshFacetsAABB2d constructor.
void compute_bbox_cell_bbox_intersections(const Box2d &box_in, std::function< void(index_t)> action) const
Computes all the intersections between a given box and the bounding boxes of all the facets.
void containing_boxes(const vec2 &p, std::function< void(index_t)> action) const
Finds all the cells such that their bounding box contain a point.
MeshFacetsAABB2d(Mesh &M, bool reorder=true)
Creates the Axis Aligned Bounding Boxes tree.
void containing_bboxes_recursive(std::function< void(index_t)> action, const vec2 &p, index_t node, index_t b, index_t e) const
Computes all the cells that have a bbox that contain a given point in a sub-tree of the AABB tree.
void initialize(Mesh &M, bool reorder=true)
Initializes the Axis Aligned Bounding Boxes tree.
index_t containing_triangle(const vec2 &p) const
Finds the index of a facet that contains a query point.
Axis Aligned Bounding Box tree of mesh facets in 3D.
bool ray_intersection(const Ray &R, double tmax=Numeric::max_float64(), index_t ignore_f=NO_INDEX) const
Tests whether there exists an intersection between a ray and the mesh.
void line_all_intersections(const vec3 &O, const vec3 &D, std::function< void(const Intersection &)> action) const
Calls a user function for all line-facet intersections.
bool segment_intersection(const vec3 &q1, const vec3 &q2) const
Tests whether this surface mesh has an intersection with a segment.
bool ray_intersection_recursive(const Ray &R, const vec3 &dirinv, double max_t, index_t ignore_f, index_t n, index_t b, index_t e) const
The recursive function used by the implementation of ray_intersection()
void initialize(Mesh &M, AABBReorderMode reorder_mode=AABB_INDIRECT)
Initializes the Axis Aligned Bounding Boxes tree.
void nearest_facet_with_hint(const vec3 &p, index_t &nearest_facet, vec3 &nearest_point, double &sq_dist) const
Computes the nearest point and nearest facet from a query point, using user-specified hint.
void ray_nearest_intersection_recursive(const Ray &R, const vec3 &dirinv, Intersection &I, index_t ignore_f, index_t n, index_t b, index_t e, index_t coord) const
The recursive function used by the implementation of ray_nearest_intersection()
void nearest_facet_recursive_filtered(const vec3 &p, index_t &nearest_facet, vec3 &nearest_point, double &sq_dist, index_t n, index_t b, index_t e, std::function< bool(index_t)> filter) const
The recursive function used by the implementation of nearest_facet_filtered().
double squared_distance(const vec3 &p) const
Computes the distance between an arbitrary 3d query point and the surface.
bool ray_nearest_intersection(const Ray &R, Intersection &I) const
Computes the nearest intersection along a ray.
MeshFacetsAABB(Mesh &M, AABBReorderMode reorder_mode)
Creates an Axis Aligned Bounding Boxes tree for facets.
MeshFacetsAABB()
MeshFacetsAABB constructor.
index_t nearest_facet(const vec3 &p, vec3 &nearest_point, double &sq_dist) const
Finds the nearest facet from an arbitrary 3d query point.
void compute_bbox_facet_bbox_intersections(const Box &box_in, std::function< void(index_t)> action) const
Computes all the intersections between a given box and the bounding boxes of all the facets.
void compute_facet_bbox_intersections(std::function< void(index_t, index_t)> action, bool concurrent=false) const
Computes all the pairs of intersecting facets.
void get_nearest_facet_hint(const vec3 &p, index_t &nearest_facet, vec3 &nearest_point, double &sq_dist) const
Computes a reasonable initialization for nearest facet search.
void ray_all_intersections_recursive(const Ray &R, const vec3 &dirinv, std::function< void(const Intersection &)> action, index_t n, index_t b, index_t e) const
The function used to implement ray_all_intersections()
void self_bbox_intersections_parallel(std::function< void(index_t, index_t)> action, bool concurrent=false) const
Computes all the pairs of intersecting elements in parallel.
void ray_all_intersections(const Ray &R, std::function< void(const Intersection &)> action) const
Calls a user function for all ray-facet intersection.
void nearest_facet_recursive(const vec3 &p, index_t &nearest_facet, vec3 &nearest_point, double &sq_dist, index_t n, index_t b, index_t e) const
The recursive function used by the implementation of nearest_facet().
bool contains(const vec3 &p) const
Tests whether a closed surface contains a point.
MeshFacetsAABB(const Mesh &M)
Creates an Axis Aligned Bounding Boxes tree for facets.
index_t nearest_facet_filtered(const vec3 &p, vec3 &nearest_point, double &sq_dist, std::function< bool(index_t)> filter) const
Finds the nearest facet from an arbitrary 3d query point taken into account only certain facets.
index_t nearest_facet(const vec3 &p) const
Finds the nearest facet from an arbitrary 3d query point.
void line_all_intersections_recursive(const vec3 &O, const vec3 &D, const vec3 &dirinv, std::function< void(const Intersection &)> action, index_t n, index_t b, index_t e) const
The function used to implement line_all_intersections()
bool segment_nearest_intersection(const vec3 &q1, const vec3 &q2, double &t, index_t &f) const
Finds the intersection between a segment and a surface that is nearest to the first extremity of the ...
index_t nb() const
Gets the number of (sub-)elements.
Vector with aligned memory allocation.
index_t size() const
Gets the number of elements.
Common include file, providing basic definitions. Should be included before anything else by all head...
Geometric functions in 2d and 3d.
The class that represents a mesh.
Global Vorpaline namespace.
bool bboxes_overlap(const Box &B1, const Box &B2)
Tests whether two Boxes have a non-empty intersection.
void get_bbox(const Mesh &M, double *xyzmin, double *xyzmax)
Gets the bounding box of a mesh.
void bbox_union(Box &target, const Box &B1, const Box &B2)
Computes the smallest Box that encloses two Boxes.
AABBReorderMode
Axis Aligned Bounding Box Tree ordering mode.
geo_index_t index_t
The type for storing and manipulating indices.
Classes for measuring time.
Stores all the information related with a ray-facet intersection.
A Ray, in parametric form.