Geogram Version 1.9.9
A programming library of geometric algorithms
Loading...
Searching...
No Matches
mesh_AABB.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef GEOGRAM_MESH_MESH_AABB
41#define GEOGRAM_MESH_MESH_AABB
42
50#include <geogram/mesh/mesh.h>
52
53namespace GEO {
54
63 AABB_INPLACE, AABB_INDIRECT, AABB_NOREORDER
64 };
65
66
71 template <class BOX> class AABB {
72
73 protected:
74
82 index_t nb, std::function<void(BOX&, index_t)> get_bbox
83 ) {
84 nb_ = nb;
85 bboxes_.resize(max_node_index(1, 0, nb) + 1);
86 // +1 because size == max_index + 1 !!!
88 }
89
90
110 std::function<void(index_t)> action, const BOX& box,
111 index_t node, index_t b, index_t e
112 ) const {
113 geo_debug_assert(e != b);
114
115 // Prune sub-tree that does not have intersection
116 if(!bboxes_overlap(box, bboxes_[node])) {
117 return;
118 }
119
120 // Leaf case
121 if(e == b+1) {
122 action(element_in_leaf(b));
123 return;
124 }
125
126 // Recursion
127 index_t m = b + (e - b) / 2;
128 index_t node_l = 2 * node;
129 index_t node_r = 2 * node + 1;
130
131 bbox_intersect_recursive(action, box, node_l, b, m);
132 bbox_intersect_recursive(action, box, node_r, m, e);
133 }
134
157 std::function<void(index_t,index_t)> action,
158 index_t node1, index_t b1, index_t e1,
159 index_t node2, index_t b2, index_t e2
160 ) const {
161 geo_debug_assert(e1 != b1);
162 geo_debug_assert(e2 != b2);
163
164 // Since we are intersecting the AABBTree with *itself*,
165 // we can prune half of the cases by skipping the test
166 // whenever node2's facet index interval is greated than
167 // node1's facet index interval.
168 if(e2 <= b1) {
169 return;
170 }
171
172 // The acceleration is here:
173 if(!bboxes_overlap(bboxes_[node1], bboxes_[node2])) {
174 return;
175 }
176
177 // Simple case: leaf - leaf intersection.
178 if(b1 + 1 == e1 && b2 + 1 == e2) {
179 action(element_in_leaf(b1), element_in_leaf(b2));
180 return;
181 }
182
183 // If node2 has more elements than node1, then
184 // intersect node2's two children with node1
185 // else
186 // intersect node1's two children with node2
187 if(e2 - b2 > e1 - b1) {
188 index_t m2 = b2 + (e2 - b2) / 2;
189 index_t node2_l = 2 * node2;
190 index_t node2_r = 2 * node2 + 1;
191 self_intersect_recursive(action, node1, b1, e1, node2_l, b2, m2);
192 self_intersect_recursive(action, node1, b1, e1, node2_r, m2, e2);
193 } else {
194 index_t m1 = b1 + (e1 - b1) / 2;
195 index_t node1_l = 2 * node1;
196 index_t node1_r = 2 * node1 + 1;
197 self_intersect_recursive(action, node1_l, b1, m1, node2, b2, e2);
198 self_intersect_recursive(action, node1_r, m1, e1, node2, b2, e2);
199 }
200 }
201
202
226 std::function<void(index_t,index_t)> action,
227 index_t node1, index_t b1, index_t e1,
228 const AABB<BOX>* other,
229 index_t node2, index_t b2, index_t e2
230 ) const {
231 geo_debug_assert(e1 != b1);
232 geo_debug_assert(e2 != b2);
233
234 // The acceleration is here:
235 if(!bboxes_overlap(bboxes_[node1], other->bboxes_[node2])) {
236 return;
237 }
238
239 // Simple case: leaf - leaf intersection.
240 if(b1 + 1 == e1 && b2 + 1 == e2) {
241 action(element_in_leaf(b1), element_in_leaf(b2));
242 return;
243 }
244
245 // If node2 has more elements than node1, then
246 // intersect node2's two children with node1
247 // else
248 // intersect node1's two children with node2
249 if(e2 - b2 > e1 - b1) {
250 index_t m2 = b2 + (e2 - b2) / 2;
251 index_t node2_l = 2 * node2;
252 index_t node2_r = 2 * node2 + 1;
254 action, node1, b1, e1, other, node2_l, b2, m2
255 );
257 action, node1, b1, e1, other, node2_r, m2, e2
258 );
259 } else {
260 index_t m1 = b1 + (e1 - b1) / 2;
261 index_t node1_l = 2 * node1;
262 index_t node1_r = 2 * node1 + 1;
264 action, node1_l, b1, m1, other, node2, b2, e2
265 );
267 action, node1_r, m1, e1, other, node2, b2, e2
268 );
269 }
270 }
271
272
280 static index_t max_node_index(index_t node_index, index_t b, index_t e) {
281 geo_debug_assert(e > b);
282 if(b + 1 == e) {
283 return node_index;
284 }
285 index_t m = b + (e - b) / 2;
286 index_t childl = 2 * node_index;
287 index_t childr = 2 * node_index + 1;
288 return std::max(
289 max_node_index(childl, b, m),
290 max_node_index(childr, m, e)
291 );
292 }
293
305 index_t node_index,
306 index_t b, index_t e,
307 std::function<void(BOX&, index_t)> get_bbox
308 ) {
309 geo_debug_assert(node_index < bboxes_.size());
310 geo_debug_assert(b != e);
311 if(b + 1 == e) {
312 get_bbox(bboxes_[node_index], element_in_leaf(b));
313 return;
314 }
315 index_t m = b + (e - b) / 2;
316 index_t childl = 2 * node_index;
317 index_t childr = 2 * node_index + 1;
318 geo_debug_assert(childl < bboxes_.size());
319 geo_debug_assert(childr < bboxes_.size());
320 init_bboxes_recursive(childl, b, m, get_bbox);
321 init_bboxes_recursive(childr, m, e, get_bbox);
322 geo_debug_assert(childl < bboxes_.size());
323 geo_debug_assert(childr < bboxes_.size());
324 bbox_union(bboxes_[node_index], bboxes_[childl], bboxes_[childr]);
325 }
326
334 bool indirect() const {
335 return (reorder_.size() != 0);
336 }
337
346 return indirect() ? reorder_[i] : i;
347 }
348
349 protected:
350 index_t nb_;
351 vector<BOX> bboxes_;
353 };
354
355 typedef AABB<Box2d> AABB2d;
356 typedef AABB<Box3d> AABB3d;
357
358 /**************************************************************/
359
364 class GEOGRAM_API MeshAABB2d : public AABB2d {
365 public:
369 MeshAABB2d() : mesh_(nullptr) {
370 }
371
376 const Mesh* mesh() const {
377 return mesh_;
378 }
379
380 protected:
381 Mesh* mesh_;
382 };
383
384 /**************************************************************/
385
390 class GEOGRAM_API MeshAABB3d : public AABB3d {
391 public:
395 MeshAABB3d() : mesh_(nullptr) {
396 }
397
402 const Mesh* mesh() const {
403 return mesh_;
404 }
405
406 protected:
407 Mesh* mesh_;
408 };
409
410 /**************************************************************/
411
417 class GEOGRAM_API MeshFacetsAABB : public MeshAABB3d {
418 public:
419
425 Intersection() :
426 t(Numeric::max_float64()),
427 f(NO_INDEX),
428 i(NO_INDEX), j(NO_INDEX), k(NO_INDEX)
429 {
430 }
432 double t;
435 index_t i,j,k;
436 double u,v;
437 };
438
439
445 }
446
461 initialize(M, reorder_mode);
462 }
463
470 initialize(const_cast<Mesh&>(M), AABB_INDIRECT);
471 }
472
486 void initialize(Mesh& M, AABBReorderMode reorder_mode = AABB_INDIRECT);
487
488#ifndef GOMGEN
489 [[deprecated("use MeshFacetsAABB(Mesh&,AABBReorderMode) instead")]]
490 MeshFacetsAABB(Mesh& M, bool reorder) {
491 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
492 }
493
494 [[deprecated("use initialize(Mesh&,AABBReorderMode) instead")]]
495 void initialize(Mesh& M, bool reorder) {
496 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
497 }
498#endif
507 std::function<void(index_t, index_t)> action
508 ) const {
509 self_intersect_recursive(
510 action,
511 1, 0, mesh_->facets.nb(),
512 1, 0, mesh_->facets.nb()
513 );
514 }
515
524 const Box& box_in, std::function<void(index_t)> action
525 ) const {
526 bbox_intersect_recursive(
527 action, box_in, 1, 0, mesh_->facets.nb()
528 );
529 }
530
541 const vec3& p, vec3& nearest_point, double& sq_dist
542 ) const {
543 if(mesh_->facets.nb() == 0) {
544 sq_dist = Numeric::max_float64();
545 return NO_INDEX;
546 }
547 index_t nearest_facet;
548 get_nearest_facet_hint(p, nearest_facet, nearest_point, sq_dist);
549 nearest_facet_recursive(
550 p,
551 nearest_facet, nearest_point, sq_dist,
552 1, 0, mesh_->facets.nb()
553 );
554 return nearest_facet;
555 }
556
563 index_t nearest_facet(const vec3& p) const {
564 vec3 nearest_point;
565 double sq_dist;
566 return nearest_facet(p, nearest_point, sq_dist);
567 }
568
569
582 const vec3& p, vec3& nearest_point, double& sq_dist,
583 std::function<bool(index_t)> filter
584 ) const {
585 if(mesh_->facets.nb() == 0) {
586 return NO_INDEX;
587 }
588 index_t nearest_facet = NO_INDEX;
589 sq_dist = Numeric::max_float64();
590 nearest_facet_recursive_filtered(
591 p,
592 nearest_facet, nearest_point, sq_dist,
593 1, 0, mesh_->facets.nb(),
594 filter
595 );
596 return nearest_facet;
597 }
598
619 const vec3& p,
620 index_t& nearest_facet, vec3& nearest_point, double& sq_dist
621 ) const {
622 if(mesh_->facets.nb() == 0) {
623 nearest_facet = NO_INDEX;
624 sq_dist = Numeric::max_float64();
625 nearest_point=vec3(0,0,0);
626 return;
627 }
628 if(nearest_facet == NO_FACET) {
629 get_nearest_facet_hint(
630 p, nearest_facet, nearest_point, sq_dist
631 );
632 }
633 nearest_facet_recursive(
634 p,
635 nearest_facet, nearest_point, sq_dist,
636 1, 0, mesh_->facets.nb()
637 );
638 }
639
646 double squared_distance(const vec3& p) const {
647 vec3 nearest_point;
648 double result;
649 nearest_facet(p, nearest_point, result);
650 return result;
651 }
652
665 const Ray& R,
666 double tmax = Numeric::max_float64(),
667 index_t ignore_f = NO_INDEX
668 ) const;
669
670
680 bool ray_nearest_intersection(const Ray& R, Intersection& I) const;
681
690 bool segment_intersection(const vec3& q1, const vec3& q2) const {
691 return ray_intersection(Ray(q1, q2-q1), 1.0);
692 }
693
706 const vec3& q1, const vec3& q2, double& t, index_t& f
707 ) const {
708 Ray R(q1, q2-q1);
709 Intersection I;
710 I.t = 1.0;
711 bool result = ray_nearest_intersection(R,I);
712 t = I.t;
713 f = I.f;
714 return result;
715 }
716
723 const Ray& R,
724 std::function<void(const Intersection&)> action
725 ) const;
726
727
736 bool contains(const vec3& p) const;
737
738 protected:
739
754 const vec3& p,
755 index_t& nearest_facet, vec3& nearest_point, double& sq_dist
756 ) const;
757
776 const vec3& p,
777 index_t& nearest_facet, vec3& nearest_point, double& sq_dist,
778 index_t n, index_t b, index_t e
779 ) const;
780
781
799 const vec3& p,
800 index_t& nearest_facet, vec3& nearest_point, double& sq_dist,
801 index_t n, index_t b, index_t e,
802 std::function<bool(index_t)> filter
803 ) const;
804
821 const Ray& R, const vec3& dirinv, double max_t, index_t ignore_f,
822 index_t n, index_t b, index_t e
823 ) const;
824
842 const Ray& R, const vec3& dirinv, Intersection& I, index_t ignore_f,
843 index_t n, index_t b, index_t e, index_t coord
844 ) const;
845
846
859 const Ray& R, const vec3& dirinv,
860 std::function<void(const Intersection&)> action,
861 index_t n, index_t b, index_t e
862 ) const;
863
864 };
865
866 /***********************************************************************/
867
873 class GEOGRAM_API MeshCellsAABB : public MeshAABB3d {
874 public:
875
881 static constexpr index_t NO_TET = NO_INDEX;
882
888 }
889
902 initialize(M, reorder_mode);
903 }
904
910 MeshCellsAABB(const Mesh& M) {
911 initialize(const_cast<Mesh&>(M), AABB_INDIRECT);
912 }
913
925 void initialize(Mesh& M, AABBReorderMode reorder_mode = AABB_INDIRECT);
926
927#ifndef GOMGEN
928 [[deprecated("use MeshCellsAABB(Mesh&,AABBReorderMode) instead")]]
929 MeshCellsAABB(Mesh& M, bool reorder) {
930 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
931 }
932
933 [[deprecated("use initialize(Mesh&,AABBReorderMode) instead")]]
934 void initialize(Mesh& M, bool reorder) {
935 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
936 }
937#endif
938
947 index_t containing_tet(const vec3& p) const {
948 geo_debug_assert(mesh_->cells.are_simplices());
949 return containing_tet_recursive(
950 p, 1, 0, mesh_->cells.nb()
951 );
952 }
953
962 const Box& box_in,
963 std::function<void(index_t)> action
964 ) const {
965 bbox_intersect_recursive(
966 action, box_in, 1, 0, mesh_->cells.nb()
967 );
968 }
969
978 const vec3& p, std::function<void(index_t)> action
979 ) const {
980 containing_bboxes_recursive(
981 action, p, 1, 0, mesh_->cells.nb()
982 );
983 }
984
993 std::function<void(index_t, index_t)> action
994 ) const {
995 self_intersect_recursive(
996 action,
997 1, 0, mesh_->cells.nb(),
998 1, 0, mesh_->cells.nb()
999 );
1000 }
1001
1012 MeshCellsAABB* other,
1013 std::function<void(index_t, index_t)> action
1014 ) const {
1015 other_intersect_recursive(
1016 action,
1017 1, 0, mesh_->cells.nb(),
1018 other,
1019 1, 0, other->mesh_->cells.nb()
1020 );
1021 }
1022
1023
1024 protected:
1025
1038 const vec3& p,
1039 index_t n, index_t b, index_t e
1040 ) const;
1041
1042
1062 std::function<void(index_t)> action,
1063 const vec3& p,
1064 index_t node, index_t b, index_t e
1065 ) const {
1066 geo_debug_assert(e != b);
1067
1068 // Prune sub-tree that does not have intersection
1069 if(!bboxes_[node].contains(p)) {
1070 return;
1071 }
1072
1073 // Leaf case
1074 if(e == b+1) {
1075 action(element_in_leaf(b));
1076 return;
1077 }
1078
1079 // Recursion
1080 index_t m = b + (e - b) / 2;
1081 index_t node_l = 2 * node;
1082 index_t node_r = 2 * node + 1;
1083
1084 containing_bboxes_recursive(action, p, node_l, b, m);
1085 containing_bboxes_recursive(action, p, node_r, m, e);
1086 }
1087 };
1088
1089/*******************************************************************/
1090
1096 class GEOGRAM_API MeshFacetsAABB2d : public MeshAABB2d {
1097 public:
1098
1104 static constexpr index_t NO_TRIANGLE = NO_INDEX;
1105
1111
1120 MeshFacetsAABB2d(Mesh& M, bool reorder = true);
1121
1130 void initialize(Mesh& M, bool reorder = true);
1131
1141 geo_debug_assert(mesh_->facets.are_simplices());
1142 return containing_triangle_recursive(
1143 p, 1, 0, mesh_->facets.nb()
1144 );
1145 }
1146
1155 const Box2d& box_in,
1156 std::function<void(index_t)> action
1157 ) const {
1158 bbox_intersect_recursive(
1159 action, box_in, 1, 0, mesh_->facets.nb()
1160 );
1161 }
1162
1171 const vec2& p, std::function<void(index_t)> action
1172 ) const {
1173 containing_bboxes_recursive(
1174 action, p, 1, 0, mesh_->facets.nb()
1175 );
1176 }
1177
1186 std::function<void(index_t, index_t)> action
1187 ) const {
1188 self_intersect_recursive(
1189 action,
1190 1, 0, mesh_->facets.nb(),
1191 1, 0, mesh_->facets.nb()
1192 );
1193 }
1194
1205 MeshFacetsAABB2d* other,
1206 std::function<void(index_t, index_t)> action
1207 ) const {
1208 other_intersect_recursive(
1209 action,
1210 1, 0, mesh_->facets.nb(),
1211 other,
1212 1, 0, other->mesh_->facets.nb()
1213 );
1214 }
1215
1216
1217 protected:
1218
1231 const vec2& p,
1232 index_t n, index_t b, index_t e
1233 ) const;
1234
1235
1255 std::function<void(index_t)> action,
1256 const vec2& p,
1257 index_t node, index_t b, index_t e
1258 ) const {
1259 geo_debug_assert(e != b);
1260
1261 // Prune sub-tree that does not have intersection
1262 if(!bboxes_[node].contains(p)) {
1263 return;
1264 }
1265
1266 // Leaf case
1267 if(e == b+1) {
1268 action(element_in_leaf(b));
1269 return;
1270 }
1271
1272 // Recursion
1273 index_t m = b + (e - b) / 2;
1274 index_t node_l = 2 * node;
1275 index_t node_r = 2 * node + 1;
1276
1277 containing_bboxes_recursive(action, p, node_l, b, m);
1278 containing_bboxes_recursive(action, p, node_r, m, e);
1279 }
1280 };
1281
1282
1283}
1284
1285#endif
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:196
Base class for Axis Aligned Bounding Box trees.
Definition mesh_AABB.h:71
bool indirect() const
Tests whether this AABB is indirect or in-place.
Definition mesh_AABB.h:334
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...
Definition mesh_AABB.h:109
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.
Definition mesh_AABB.h:156
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.
Definition mesh_AABB.h:225
static index_t max_node_index(index_t node_index, index_t b, index_t e)
Computes the maximum node index in a subtree.
Definition mesh_AABB.h:280
vector< index_t > reorder_
Definition mesh_AABB.h:352
void initialize(index_t nb, std::function< void(BOX &, index_t)> get_bbox)
Initializes this AABB.
Definition mesh_AABB.h:81
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.
Definition mesh_AABB.h:304
index_t element_in_leaf(index_t i) const
Gets the element stored in a leaf node.
Definition mesh_AABB.h:345
Axis-aligned bounding box.
Definition geometry.h:752
Axis-aligned bounding box.
Definition geometry.h:689
Base class for Axis Aligned Bounding Box trees of mesh elements with 2d boxes.
Definition mesh_AABB.h:364
const Mesh * mesh() const
Gets the mesh.
Definition mesh_AABB.h:376
MeshAABB2d()
MeshAABB2d constructor.
Definition mesh_AABB.h:369
Base class for Axis Aligned Bounding Box trees of mesh elements with 3d boxes.
Definition mesh_AABB.h:390
const Mesh * mesh() const
Gets the mesh.
Definition mesh_AABB.h:402
MeshAABB3d()
MeshAABB3d constructor.
Definition mesh_AABB.h:395
Axis Aligned Bounding Box tree of mesh cells.
Definition mesh_AABB.h:873
void compute_cell_bbox_intersections(std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting cells.
Definition mesh_AABB.h:992
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.
Definition mesh_AABB.h:977
MeshCellsAABB()
MeshCellsAABB constructor.
Definition mesh_AABB.h:887
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.
Definition mesh_AABB.h:947
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.
Definition mesh_AABB.h:961
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.
Definition mesh_AABB.h:1061
MeshCellsAABB(Mesh &M, AABBReorderMode reorder_mode)
Creates an Axis Aligned Bounding Boxes tree for mesh cells.
Definition mesh_AABB.h:901
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.
Definition mesh_AABB.h:1011
MeshCellsAABB(const Mesh &M)
Creates an Axis Aligned Bounding Boxes tree for mesh cells.
Definition mesh_AABB.h:910
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.
Definition mesh_AABB.h:1096
void compute_facet_bbox_intersections(std::function< void(index_t, index_t)> action) const
Computes all the pairs of intersecting facets.
Definition mesh_AABB.h:1185
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.
Definition mesh_AABB.h:1204
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.
Definition mesh_AABB.h:1154
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.
Definition mesh_AABB.h:1170
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.
Definition mesh_AABB.h:1254
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.
Definition mesh_AABB.h:1140
Axis Aligned Bounding Box tree of mesh facets in 3D.
Definition mesh_AABB.h:417
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.
Definition mesh_AABB.h:690
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.
Definition mesh_AABB.h:618
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.
Definition mesh_AABB.h:646
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.
Definition mesh_AABB.h:460
MeshFacetsAABB()
MeshFacetsAABB constructor.
Definition mesh_AABB.h:444
index_t nearest_facet(const vec3 &p, vec3 &nearest_point, double &sq_dist) const
Finds the nearest facet from an arbitrary 3d query point.
Definition mesh_AABB.h:540
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.
Definition mesh_AABB.h:523
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.
Definition mesh_AABB.h:506
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.
Definition mesh_AABB.h:469
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.
Definition mesh_AABB.h:581
index_t nearest_facet(const vec3 &p) const
Finds the nearest facet from an arbitrary 3d query point.
Definition mesh_AABB.h:563
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 ...
Definition mesh_AABB.h:705
index_t nb() const
Gets the number of (sub-)elements.
Definition mesh.h:98
Represents a mesh.
Definition mesh.h:3132
Vector with aligned memory allocation.
Definition memory.h:710
index_t size() const
Gets the number of elements.
Definition memory.h:756
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.
Definition basic.h:55
bool bboxes_overlap(const Box &B1, const Box &B2)
Tests whether two Boxes have a non-empty intersection.
Definition geometry.h:721
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.
Definition geometry.h:740
AABBReorderMode
Axis Aligned Bounding Box Tree ordering mode.
Definition mesh_AABB.h:62
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:330
Stores all the information related with a ray-facet intersection.
Definition mesh_AABB.h:424
A Ray, in parametric form.
Definition geometry.h:940