40#ifndef GEOGRAM_MESH_MESH_AABB
41#define GEOGRAM_MESH_MESH_AABB
63 AABB_INPLACE, AABB_INDIRECT, AABB_NOREORDER
71 template <
class BOX>
class AABB {
110 std::function<
void(
index_t)> action,
const BOX& box,
178 if(b1 + 1 == e1 && b2 + 1 == e2) {
187 if(e2 - b2 > e1 - b1) {
188 index_t m2 = b2 + (e2 - b2) / 2;
190 index_t node2_r = 2 * node2 + 1;
194 index_t m1 = b1 + (e1 - b1) / 2;
196 index_t node1_r = 2 * node1 + 1;
240 if(b1 + 1 == e1 && b2 + 1 == e2) {
249 if(e2 - b2 > e1 - b1) {
250 index_t m2 = b2 + (e2 - b2) / 2;
252 index_t node2_r = 2 * node2 + 1;
254 action, node1, b1, e1, other, node2_l, b2, m2
257 action, node1, b1, e1, other, node2_r, m2, e2
260 index_t m1 = b1 + (e1 - b1) / 2;
262 index_t node1_r = 2 * node1 + 1;
264 action, node1_l, b1, m1, other, node2, b2, e2
267 action, node1_r, m1, e1, other, node2, b2, e2
286 index_t childl = 2 * node_index;
287 index_t childr = 2 * node_index + 1;
316 index_t childl = 2 * node_index;
317 index_t childr = 2 * node_index + 1;
324 bbox_union(bboxes_[node_index], bboxes_[childl], bboxes_[childr]);
426 t(Numeric::max_float64()),
428 i(NO_INDEX), j(NO_INDEX), k(NO_INDEX)
461 initialize(M, reorder_mode);
470 initialize(
const_cast<Mesh&
>(M), AABB_INDIRECT);
489 [[deprecated(
"use MeshFacetsAABB(Mesh&,AABBReorderMode) instead")]]
491 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
494 [[deprecated(
"use initialize(Mesh&,AABBReorderMode) instead")]]
495 void initialize(
Mesh& M,
bool reorder) {
496 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
509 self_intersect_recursive(
511 1, 0, mesh_->facets.nb(),
512 1, 0, mesh_->facets.nb()
524 const Box& box_in, std::function<
void(
index_t)> action
526 bbox_intersect_recursive(
527 action, box_in, 1, 0, mesh_->facets.nb()
539 const vec3& p,
vec3& nearest_point,
double& sq_dist
542 get_nearest_facet_hint(p, nearest_facet, nearest_point, sq_dist);
543 nearest_facet_recursive(
545 nearest_facet, nearest_point, sq_dist,
546 1, 0, mesh_->facets.nb()
548 return nearest_facet;
559 return nearest_facet(p, nearest_point, sq_dist);
575 const vec3& p,
vec3& nearest_point,
double& sq_dist,
576 std::function<
bool(
index_t)> filter
578 index_t nearest_facet = NO_INDEX;
579 sq_dist = Numeric::max_float64();
580 nearest_facet_recursive_filtered(
582 nearest_facet, nearest_point, sq_dist,
583 1, 0, mesh_->facets.nb(),
586 return nearest_facet;
610 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist
612 if(nearest_facet == NO_FACET) {
613 get_nearest_facet_hint(
614 p, nearest_facet, nearest_point, sq_dist
617 nearest_facet_recursive(
619 nearest_facet, nearest_point, sq_dist,
620 1, 0, mesh_->facets.nb()
633 nearest_facet(p, nearest_point, result);
650 double tmax = Numeric::max_float64(),
675 return ray_intersection(
Ray(q1, q2-q1), 1.0);
695 bool result = ray_nearest_intersection(R,I);
728 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist
750 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist,
773 index_t& nearest_facet,
vec3& nearest_point,
double& sq_dist,
775 std::function<
bool(
index_t)> filter
832 const Ray& R,
const vec3& dirinv,
875 initialize(M, reorder_mode);
884 initialize(
const_cast<Mesh&
>(M), AABB_INDIRECT);
901 [[deprecated(
"use MeshCellsAABB(Mesh&,AABBReorderMode) instead")]]
903 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
906 [[deprecated(
"use initialize(Mesh&,AABBReorderMode) instead")]]
907 void initialize(
Mesh& M,
bool reorder) {
908 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
922 return containing_tet_recursive(
923 p, 1, 0, mesh_->cells.nb()
936 std::function<
void(
index_t)> action
938 bbox_intersect_recursive(
939 action, box_in, 1, 0, mesh_->cells.nb()
953 containing_bboxes_recursive(
954 action, p, 1, 0, mesh_->cells.nb()
968 self_intersect_recursive(
970 1, 0, mesh_->cells.nb(),
971 1, 0, mesh_->cells.nb()
988 other_intersect_recursive(
990 1, 0, mesh_->cells.nb(),
992 1, 0, other->mesh_->cells.
nb()
1035 std::function<
void(
index_t)> action,
1042 if(!bboxes_[node].contains(p)) {
1048 action(element_in_leaf(b));
1055 index_t node_r = 2 * node + 1;
1057 containing_bboxes_recursive(action, p, node_l, b, m);
1058 containing_bboxes_recursive(action, p, node_r, m, e);
1115 return containing_triangle_recursive(
1116 p, 1, 0, mesh_->facets.nb()
1128 const Box2d& box_in,
1129 std::function<
void(
index_t)> action
1131 bbox_intersect_recursive(
1132 action, box_in, 1, 0, mesh_->facets.nb()
1144 const vec2& p, std::function<
void(
index_t)> action
1146 containing_bboxes_recursive(
1147 action, p, 1, 0, mesh_->facets.nb()
1161 self_intersect_recursive(
1163 1, 0, mesh_->facets.nb(),
1164 1, 0, mesh_->facets.nb()
1181 other_intersect_recursive(
1183 1, 0, mesh_->facets.nb(),
1185 1, 0, other->mesh_->facets.
nb()
1228 std::function<
void(
index_t)> action,
1235 if(!bboxes_[node].contains(p)) {
1241 action(element_in_leaf(b));
1248 index_t node_r = 2 * node + 1;
1250 containing_bboxes_recursive(action, p, node_l, b, m);
1251 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 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.
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 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 ray_all_intersections(const Ray &R, std::function< void(const Intersection &)> action) const
Calls a user function for all ray-facet intersection.
void compute_facet_bbox_intersections(std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting facets.
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().
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.
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.
Stores all the information related with a ray-facet intersection.
A Ray, in parametric form.