Graphite Version 3
An experimental 3D geometry processing program
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>
53
54namespace GEO {
55
64 AABB_INPLACE, AABB_INDIRECT, AABB_NOREORDER
65 };
66
71 template <class BOX> class AABB {
72
73 public:
79 void enlarge_boxes(double amount) {
80 for(auto& B: bboxes_) {
81 B.enlarge(amount);
82 }
83 }
84
85 protected:
86
94 index_t nb, std::function<void(BOX&, index_t)> get_bbox
95 ) {
96 nb_ = nb;
97 bboxes_.resize(max_node_index(1, 0, nb) + 1);
98 // +1 because size == max_index + 1 !!!
100 }
101
121 std::function<void(index_t)> action, const BOX& box,
122 index_t node, index_t b, index_t e
123 ) const {
124 geo_debug_assert(e != b);
125
126 // Prune sub-tree that does not have intersection
127 if(!bboxes_overlap(box, bboxes_[node])) {
128 return;
129 }
130
131 // Leaf case
132 if(e == b+1) {
133 action(element_in_leaf(b));
134 return;
135 }
136
137 // Recursion
138 index_t m = b + (e - b) / 2;
139 index_t node_l = 2 * node;
140 index_t node_r = 2 * node + 1;
141
142 bbox_intersect_recursive(action, box, node_l, b, m);
143 bbox_intersect_recursive(action, box, node_r, m, e);
144 }
145
168 std::function<void(index_t,index_t)> action,
169 index_t node1, index_t b1, index_t e1,
170 index_t node2, index_t b2, index_t e2
171 ) const {
172 geo_debug_assert(e1 != b1);
173 geo_debug_assert(e2 != b2);
174
175 // Since we are intersecting the AABBTree with *itself*,
176 // we can prune half of the cases by skipping the test
177 // whenever node2's facet index interval is greater than
178 // node1's facet index interval.
179 if(e2 <= b1) {
180 return;
181 }
182
183 // The acceleration is here:
184 if(
185 (node1 != node2) &&
186 !bboxes_overlap(bboxes_[node1], bboxes_[node2])
187 ) {
188 return;
189 }
190
191 // Simple case: leaf - leaf intersection.
192 if(b1 + 1 == e1 && b2 + 1 == e2) {
193 if(b1 != b2) {
194 action(element_in_leaf(b1), element_in_leaf(b2));
195 }
196 return;
197 }
198
199 // If node2 has more elements than node1, then
200 // intersect node2's two children with node1
201 // else
202 // intersect node1's two children with node2
203 if(e2 - b2 > e1 - b1) {
204 index_t m2 = b2 + (e2 - b2) / 2;
205 index_t node2_l = 2 * node2;
206 index_t node2_r = 2 * node2 + 1;
207 self_intersect_recursive(action, node1, b1, e1, node2_l, b2, m2);
208 self_intersect_recursive(action, node1, b1, e1, node2_r, m2, e2);
209 } else {
210 index_t m1 = b1 + (e1 - b1) / 2;
211 index_t node1_l = 2 * node1;
212 index_t node1_r = 2 * node1 + 1;
213 self_intersect_recursive(action, node1_l, b1, m1, node2, b2, e2);
214 self_intersect_recursive(action, node1_r, m1, e1, node2, b2, e2);
215 }
216 }
217
241 std::function<void(index_t,index_t)> action,
242 index_t node1, index_t b1, index_t e1,
243 const AABB<BOX>* other,
244 index_t node2, index_t b2, index_t e2
245 ) const {
246 geo_debug_assert(e1 != b1);
247 geo_debug_assert(e2 != b2);
248
249 // The acceleration is here:
250 if(!bboxes_overlap(bboxes_[node1], other->bboxes_[node2])) {
251 return;
252 }
253
254 // Simple case: leaf - leaf intersection.
255 if(b1 + 1 == e1 && b2 + 1 == e2) {
256 action(element_in_leaf(b1), element_in_leaf(b2));
257 return;
258 }
259
260 // If node2 has more elements than node1, then
261 // intersect node2's two children with node1
262 // else
263 // intersect node1's two children with node2
264 if(e2 - b2 > e1 - b1) {
265 index_t m2 = b2 + (e2 - b2) / 2;
266 index_t node2_l = 2 * node2;
267 index_t node2_r = 2 * node2 + 1;
269 action, node1, b1, e1, other, node2_l, b2, m2
270 );
272 action, node1, b1, e1, other, node2_r, m2, e2
273 );
274 } else {
275 index_t m1 = b1 + (e1 - b1) / 2;
276 index_t node1_l = 2 * node1;
277 index_t node1_r = 2 * node1 + 1;
279 action, node1_l, b1, m1, other, node2, b2, e2
280 );
282 action, node1_r, m1, e1, other, node2, b2, e2
283 );
284 }
285 }
286
287
295 static index_t max_node_index(index_t node_index, index_t b, index_t e) {
296 geo_debug_assert(e > b);
297 if(b + 1 == e) {
298 return node_index;
299 }
300 index_t m = b + (e - b) / 2;
301 index_t childl = 2 * node_index;
302 index_t childr = 2 * node_index + 1;
303 return std::max(
304 max_node_index(childl, b, m),
305 max_node_index(childr, m, e)
306 );
307 }
308
320 index_t node_index,
321 index_t b, index_t e,
322 std::function<void(BOX&, index_t)> get_bbox
323 ) {
324 geo_debug_assert(node_index < bboxes_.size());
325 geo_debug_assert(b != e);
326 if(b + 1 == e) {
327 get_bbox(bboxes_[node_index], element_in_leaf(b));
328 return;
329 }
330 index_t m = b + (e - b) / 2;
331 index_t childl = 2 * node_index;
332 index_t childr = 2 * node_index + 1;
333 geo_debug_assert(childl < bboxes_.size());
334 geo_debug_assert(childr < bboxes_.size());
335 init_bboxes_recursive(childl, b, m, get_bbox);
336 init_bboxes_recursive(childr, m, e, get_bbox);
337 geo_debug_assert(childl < bboxes_.size());
338 geo_debug_assert(childr < bboxes_.size());
339 bbox_union(bboxes_[node_index], bboxes_[childl], bboxes_[childr]);
340 }
341
349 bool indirect() const {
350 return (reorder_.size() != 0);
351 }
352
361 return indirect() ? reorder_[i] : i;
362 }
363
364 protected:
365 index_t nb_;
366 vector<BOX> bboxes_;
368 };
369
370 typedef AABB<Box2d> AABB2d;
371 typedef AABB<Box3d> AABB3d;
372
373 /**************************************************************/
374
379 class GEOGRAM_API MeshAABB2d : public AABB2d {
380 public:
384 MeshAABB2d() : mesh_(nullptr) {
385 }
386
391 const Mesh* mesh() const {
392 return mesh_;
393 }
394
395 protected:
396 Mesh* mesh_;
397 };
398
399 /**************************************************************/
400
405 class GEOGRAM_API MeshAABB3d : public AABB3d {
406 public:
410 MeshAABB3d() : mesh_(nullptr) {
411 }
412
417 const Mesh* mesh() const {
418 return mesh_;
419 }
420
421 protected:
422 Mesh* mesh_;
423 };
424
425 /**************************************************************/
426
432 class GEOGRAM_API MeshFacetsAABB : public MeshAABB3d {
433 public:
434
440 Intersection() :
441 t(Numeric::max_float64()),
442 f(NO_INDEX),
443 i(NO_INDEX), j(NO_INDEX), k(NO_INDEX)
444 {
445 }
447 double t;
450 index_t i,j,k;
451 double u,v;
452 };
453
454
460 }
461
476 initialize(M, reorder_mode);
477 }
478
485 initialize(const_cast<Mesh&>(M), AABB_INDIRECT);
486 }
487
501 void initialize(Mesh& M, AABBReorderMode reorder_mode = AABB_INDIRECT);
502
503#ifndef GOMGEN
504 [[deprecated("use MeshFacetsAABB(Mesh&,AABBReorderMode) instead")]]
505 MeshFacetsAABB(Mesh& M, bool reorder) {
506 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
507 }
508
509 [[deprecated("use initialize(Mesh&,AABBReorderMode) instead")]]
510 void initialize(Mesh& M, bool reorder) {
511 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
512 }
513#endif
526 std::function<void(index_t, index_t)> action,
527 bool concurrent = false
528 ) const {
529 if(
530 Process::maximum_concurrent_threads() <= 1 ||
531 mesh_->facets.nb() <= 1024
532 ) {
533 self_intersect_recursive(
534 action,
535 1, 0, mesh_->facets.nb(),
536 1, 0, mesh_->facets.nb()
537 );
538 } else {
539 self_bbox_intersections_parallel(action, concurrent);
540 }
541
542 }
543
552 const Box& box_in, std::function<void(index_t)> action
553 ) const {
554 bbox_intersect_recursive(
555 action, box_in, 1, 0, mesh_->facets.nb()
556 );
557 }
558
569 const vec3& p, vec3& nearest_point, double& sq_dist
570 ) const {
571 if(mesh_->facets.nb() == 0) {
572 sq_dist = Numeric::max_float64();
573 return NO_INDEX;
574 }
575 index_t nearest_facet;
576 get_nearest_facet_hint(p, nearest_facet, nearest_point, sq_dist);
577 nearest_facet_recursive(
578 p,
579 nearest_facet, nearest_point, sq_dist,
580 1, 0, mesh_->facets.nb()
581 );
582 return nearest_facet;
583 }
584
591 index_t nearest_facet(const vec3& p) const {
592 vec3 nearest_point;
593 double sq_dist;
594 return nearest_facet(p, nearest_point, sq_dist);
595 }
596
597
610 const vec3& p, vec3& nearest_point, double& sq_dist,
611 std::function<bool(index_t)> filter
612 ) const {
613 if(mesh_->facets.nb() == 0) {
614 return NO_INDEX;
615 }
616 index_t nearest_facet = NO_INDEX;
617 sq_dist = Numeric::max_float64();
618 nearest_facet_recursive_filtered(
619 p,
620 nearest_facet, nearest_point, sq_dist,
621 1, 0, mesh_->facets.nb(),
622 filter
623 );
624 return nearest_facet;
625 }
626
647 const vec3& p,
648 index_t& nearest_facet, vec3& nearest_point, double& sq_dist
649 ) const {
650 if(mesh_->facets.nb() == 0) {
651 nearest_facet = NO_INDEX;
652 sq_dist = Numeric::max_float64();
653 nearest_point=vec3(0,0,0);
654 return;
655 }
656 if(nearest_facet == NO_FACET) {
657 get_nearest_facet_hint(
658 p, nearest_facet, nearest_point, sq_dist
659 );
660 }
661 nearest_facet_recursive(
662 p,
663 nearest_facet, nearest_point, sq_dist,
664 1, 0, mesh_->facets.nb()
665 );
666 }
667
674 double squared_distance(const vec3& p) const {
675 vec3 nearest_point;
676 double result;
677 nearest_facet(p, nearest_point, result);
678 return result;
679 }
680
693 const Ray& R,
694 double tmax = Numeric::max_float64(),
695 index_t ignore_f = NO_INDEX
696 ) const;
697
698
708 bool ray_nearest_intersection(const Ray& R, Intersection& I) const;
709
718 bool segment_intersection(const vec3& q1, const vec3& q2) const {
719 return ray_intersection(Ray(q1, q2-q1), 1.0);
720 }
721
734 const vec3& q1, const vec3& q2, double& t, index_t& f
735 ) const {
736 Ray R(q1, q2-q1);
737 Intersection I;
738 I.t = 1.0;
739 bool result = ray_nearest_intersection(R,I);
740 t = I.t;
741 f = I.f;
742 return result;
743 }
744
751 const Ray& R,
752 std::function<void(const Intersection&)> action
753 ) const;
754
755
763 const vec3& O, const vec3& D,
764 std::function<void(const Intersection&)> action
765 ) const;
766
767
776 bool contains(const vec3& p) const;
777
778 protected:
779
794 const vec3& p,
795 index_t& nearest_facet, vec3& nearest_point, double& sq_dist
796 ) const;
797
816 const vec3& p,
817 index_t& nearest_facet, vec3& nearest_point, double& sq_dist,
818 index_t n, index_t b, index_t e
819 ) const;
820
821
839 const vec3& p,
840 index_t& nearest_facet, vec3& nearest_point, double& sq_dist,
841 index_t n, index_t b, index_t e,
842 std::function<bool(index_t)> filter
843 ) const;
844
861 const Ray& R, const vec3& dirinv, double max_t, index_t ignore_f,
862 index_t n, index_t b, index_t e
863 ) const;
864
882 const Ray& R, const vec3& dirinv, Intersection& I, index_t ignore_f,
883 index_t n, index_t b, index_t e, index_t coord
884 ) const;
885
886
899 const Ray& R, const vec3& dirinv,
900 std::function<void(const Intersection&)> action,
901 index_t n, index_t b, index_t e
902 ) const;
903
904
918 const vec3& O, const vec3& D, const vec3& dirinv,
919 std::function<void(const Intersection&)> action,
920 index_t n, index_t b, index_t e
921 ) const;
922
923
936 std::function<void(index_t, index_t)> action, bool concurrent=false
937 ) const;
938 };
939
940 /***********************************************************************/
941
947 class GEOGRAM_API MeshCellsAABB : public MeshAABB3d {
948 public:
949
955 static constexpr index_t NO_TET = NO_INDEX;
956
962 }
963
976 initialize(M, reorder_mode);
977 }
978
984 MeshCellsAABB(const Mesh& M) {
985 initialize(const_cast<Mesh&>(M), AABB_INDIRECT);
986 }
987
999 void initialize(Mesh& M, AABBReorderMode reorder_mode = AABB_INDIRECT);
1000
1001#ifndef GOMGEN
1002 [[deprecated("use MeshCellsAABB(Mesh&,AABBReorderMode) instead")]]
1003 MeshCellsAABB(Mesh& M, bool reorder) {
1004 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
1005 }
1006
1007 [[deprecated("use initialize(Mesh&,AABBReorderMode) instead")]]
1008 void initialize(Mesh& M, bool reorder) {
1009 initialize(M, reorder ? AABB_INPLACE : AABB_NOREORDER);
1010 }
1011#endif
1012
1021 index_t containing_tet(const vec3& p) const {
1022 geo_debug_assert(mesh_->cells.are_simplices());
1023 return containing_tet_recursive(
1024 p, 1, 0, mesh_->cells.nb()
1025 );
1026 }
1027
1036 const Box& box_in,
1037 std::function<void(index_t)> action
1038 ) const {
1039 bbox_intersect_recursive(
1040 action, box_in, 1, 0, mesh_->cells.nb()
1041 );
1042 }
1043
1052 const vec3& p, std::function<void(index_t)> action
1053 ) const {
1054 containing_bboxes_recursive(
1055 action, p, 1, 0, mesh_->cells.nb()
1056 );
1057 }
1058
1067 std::function<void(index_t, index_t)> action
1068 ) const {
1069 self_intersect_recursive(
1070 action,
1071 1, 0, mesh_->cells.nb(),
1072 1, 0, mesh_->cells.nb()
1073 );
1074 }
1075
1086 MeshCellsAABB* other,
1087 std::function<void(index_t, index_t)> action
1088 ) const {
1089 other_intersect_recursive(
1090 action,
1091 1, 0, mesh_->cells.nb(),
1092 other,
1093 1, 0, other->mesh_->cells.nb()
1094 );
1095 }
1096
1097
1098 protected:
1099
1112 const vec3& p,
1113 index_t n, index_t b, index_t e
1114 ) const;
1115
1116
1136 std::function<void(index_t)> action,
1137 const vec3& p,
1138 index_t node, index_t b, index_t e
1139 ) const {
1140 geo_debug_assert(e != b);
1141
1142 // Prune sub-tree that does not have intersection
1143 if(!bboxes_[node].contains(p)) {
1144 return;
1145 }
1146
1147 // Leaf case
1148 if(e == b+1) {
1149 action(element_in_leaf(b));
1150 return;
1151 }
1152
1153 // Recursion
1154 index_t m = b + (e - b) / 2;
1155 index_t node_l = 2 * node;
1156 index_t node_r = 2 * node + 1;
1157
1158 containing_bboxes_recursive(action, p, node_l, b, m);
1159 containing_bboxes_recursive(action, p, node_r, m, e);
1160 }
1161 };
1162
1163/*******************************************************************/
1164
1170 class GEOGRAM_API MeshFacetsAABB2d : public MeshAABB2d {
1171 public:
1172
1178 static constexpr index_t NO_TRIANGLE = NO_INDEX;
1179
1185
1194 MeshFacetsAABB2d(Mesh& M, bool reorder = true);
1195
1204 void initialize(Mesh& M, bool reorder = true);
1205
1215 geo_debug_assert(mesh_->facets.are_simplices());
1216 return containing_triangle_recursive(
1217 p, 1, 0, mesh_->facets.nb()
1218 );
1219 }
1220
1229 const Box2d& box_in,
1230 std::function<void(index_t)> action
1231 ) const {
1232 bbox_intersect_recursive(
1233 action, box_in, 1, 0, mesh_->facets.nb()
1234 );
1235 }
1236
1245 const vec2& p, std::function<void(index_t)> action
1246 ) const {
1247 containing_bboxes_recursive(
1248 action, p, 1, 0, mesh_->facets.nb()
1249 );
1250 }
1251
1260 std::function<void(index_t, index_t)> action
1261 ) const {
1262 self_intersect_recursive(
1263 action,
1264 1, 0, mesh_->facets.nb(),
1265 1, 0, mesh_->facets.nb()
1266 );
1267 }
1268
1279 MeshFacetsAABB2d* other,
1280 std::function<void(index_t, index_t)> action
1281 ) const {
1282 other_intersect_recursive(
1283 action,
1284 1, 0, mesh_->facets.nb(),
1285 other,
1286 1, 0, other->mesh_->facets.nb()
1287 );
1288 }
1289
1290
1291 protected:
1292
1305 const vec2& p,
1306 index_t n, index_t b, index_t e
1307 ) const;
1308
1309
1329 std::function<void(index_t)> action,
1330 const vec2& p,
1331 index_t node, index_t b, index_t e
1332 ) const {
1333 geo_debug_assert(e != b);
1334
1335 // Prune sub-tree that does not have intersection
1336 if(!bboxes_[node].contains(p)) {
1337 return;
1338 }
1339
1340 // Leaf case
1341 if(e == b+1) {
1342 action(element_in_leaf(b));
1343 return;
1344 }
1345
1346 // Recursion
1347 index_t m = b + (e - b) / 2;
1348 index_t node_l = 2 * node;
1349 index_t node_r = 2 * node + 1;
1350
1351 containing_bboxes_recursive(action, p, node_l, b, m);
1352 containing_bboxes_recursive(action, p, node_r, m, e);
1353 }
1354 };
1355
1356
1357}
1358
1359#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:349
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:120
void enlarge_boxes(double amount)
Enlarges all the boxes.
Definition mesh_AABB.h:79
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:167
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:240
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:295
vector< index_t > reorder_
Definition mesh_AABB.h:367
void initialize(index_t nb, std::function< void(BOX &, index_t)> get_bbox)
Initializes this AABB.
Definition mesh_AABB.h:93
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:319
index_t element_in_leaf(index_t i) const
Gets the element stored in a leaf node.
Definition mesh_AABB.h:360
Axis-aligned bounding box.
Definition geometry.h:767
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:379
const Mesh * mesh() const
Gets the mesh.
Definition mesh_AABB.h:391
MeshAABB2d()
MeshAABB2d constructor.
Definition mesh_AABB.h:384
Base class for Axis Aligned Bounding Box trees of mesh elements with 3d boxes.
Definition mesh_AABB.h:405
const Mesh * mesh() const
Gets the mesh.
Definition mesh_AABB.h:417
MeshAABB3d()
MeshAABB3d constructor.
Definition mesh_AABB.h:410
Axis Aligned Bounding Box tree of mesh cells.
Definition mesh_AABB.h:947
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:1066
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:1051
MeshCellsAABB()
MeshCellsAABB constructor.
Definition mesh_AABB.h:961
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:1021
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:1035
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:1135
MeshCellsAABB(Mesh &M, AABBReorderMode reorder_mode)
Creates an Axis Aligned Bounding Boxes tree for mesh cells.
Definition mesh_AABB.h:975
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:1085
MeshCellsAABB(const Mesh &M)
Creates an Axis Aligned Bounding Boxes tree for mesh cells.
Definition mesh_AABB.h:984
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:1170
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:1259
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:1278
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:1228
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:1244
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:1328
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:1214
Axis Aligned Bounding Box tree of mesh facets in 3D.
Definition mesh_AABB.h:432
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.
Definition mesh_AABB.h:718
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:646
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:674
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:475
MeshFacetsAABB()
MeshFacetsAABB constructor.
Definition mesh_AABB.h:459
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:568
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:551
void compute_facet_bbox_intersections(std::function< void(index_t, index_t)> action, bool concurrent=false) const
Computes all the pairs of intersecting facets.
Definition mesh_AABB.h:525
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.
Definition mesh_AABB.h:484
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:609
index_t nearest_facet(const vec3 &p) const
Finds the nearest facet from an arbitrary 3d query point.
Definition mesh_AABB.h:591
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 ...
Definition mesh_AABB.h:733
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:702
index_t size() const
Gets the number of elements.
Definition memory.h:748
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.
Definition geometry.h:736
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:755
AABBReorderMode
Axis Aligned Bounding Box Tree ordering mode.
Definition mesh_AABB.h:63
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:330
Classes for measuring time.
Stores all the information related with a ray-facet intersection.
Definition mesh_AABB.h:439
A Ray, in parametric form.
Definition geometry.h:967