AABB.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #ifndef IGL_AABB_H
  9. #define IGL_AABB_H
  10. #include "Hit.h"
  11. #include "igl_inline.h"
  12. #include <cassert>
  13. #include <Eigen/Core>
  14. #include <Eigen/Geometry>
  15. #include <vector>
  16. namespace igl
  17. {
  18. /// Implementation of semi-general purpose axis-aligned bounding box hierarchy.
  19. /// The mesh (V,Ele) is stored and managed by the caller and each routine here
  20. /// simply takes it as references (it better not change between calls).
  21. ///
  22. /// It's a little annoying that the Dimension is a template parameter and not
  23. /// picked up at run time from V. This leads to duplicated code for 2d/3d (up to
  24. /// dim).
  25. ///
  26. /// @tparam DerivedV Matrix type of vertex positions (e.g., `Eigen::MatrixXd`)
  27. /// @tparam DIM Dimension of mesh vertex positions (2 or 3)
  28. template <typename DerivedV, int DIM>
  29. class AABB
  30. {
  31. public:
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // Member variables
  34. ///////////////////////////////////////////////////////////////////////////////
  35. /// Scalar type of vertex positions (e.g., `double`)
  36. typedef typename DerivedV::Scalar Scalar;
  37. /// Fixed-size (`DIM`) RowVector type using `Scalar`
  38. typedef Eigen::Matrix<Scalar,1,DIM> RowVectorDIMS;
  39. /// Fixed-size (`DIM`) (Column)Vector type using `Scalar`
  40. typedef Eigen::Matrix<Scalar,DIM,1> VectorDIMS;
  41. /// Fixed-width (`DIM`) Matrix type using `Scalar`
  42. typedef Eigen::Matrix<Scalar,Eigen::Dynamic,DIM> MatrixXDIMS;
  43. /// Pointer to "left" child node (`nullptr` if leaf)
  44. // Shared pointers are slower...
  45. AABB * m_left;
  46. /// Pointer to "right" child node (`nullptr` if leaf)
  47. AABB * m_right;
  48. /// Pointer to "parent" node (`nullptr` if root)
  49. AABB * m_parent;
  50. /// Axis-Aligned Bounding Box containing this node
  51. Eigen::AlignedBox<Scalar,DIM> m_box;
  52. /// Index of single primitive in this node if full leaf, otherwise -1 for non-leaf
  53. int m_primitive;
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // Non-templated member functions
  56. ///////////////////////////////////////////////////////////////////////////////
  57. //Scalar m_low_sqr_d;
  58. //int m_depth;
  59. /// @private
  60. AABB():
  61. m_left(nullptr), m_right(nullptr),m_parent(nullptr),
  62. m_box(), m_primitive(-1)
  63. //m_low_sqr_d(std::numeric_limits<double>::infinity()),
  64. //m_depth(0)
  65. {
  66. static_assert(DerivedV::ColsAtCompileTime == DIM || DerivedV::ColsAtCompileTime == Eigen::Dynamic,"DerivedV::ColsAtCompileTime == DIM || DerivedV::ColsAtCompileTime == Eigen::Dynamic");
  67. }
  68. /// @private
  69. // http://stackoverflow.com/a/3279550/148668
  70. AABB(const AABB& other):
  71. m_left (other.m_left ? new AABB(*other.m_left) : nullptr),
  72. m_right(other.m_right ? new AABB(*other.m_right) : nullptr),
  73. m_parent(other.m_parent),
  74. m_box(other.m_box),
  75. m_primitive(other.m_primitive)
  76. //m_low_sqr_d(other.m_low_sqr_d),
  77. //m_depth(std::max(
  78. // m_left ? m_left->m_depth + 1 : 0,
  79. // m_right ? m_right->m_depth + 1 : 0))
  80. {
  81. if(m_left) { m_left->m_parent = this; }
  82. if(m_right) { m_right->m_parent = this; }
  83. }
  84. /// @private
  85. // copy-swap idiom
  86. friend void swap(AABB& first, AABB& second)
  87. {
  88. // Enable ADL
  89. using std::swap;
  90. swap(first.m_left,second.m_left);
  91. swap(first.m_right,second.m_right);
  92. swap(first.m_parent,second.m_parent);
  93. swap(first.m_box,second.m_box);
  94. swap(first.m_primitive,second.m_primitive);
  95. //swap(first.m_low_sqr_d,second.m_low_sqr_d);
  96. //swap(first.m_depth,second.m_depth);
  97. }
  98. /// @private
  99. // Pass-by-value (aka copy)
  100. AABB& operator=(AABB other)
  101. {
  102. swap(*this,other);
  103. return *this;
  104. }
  105. /// @private
  106. AABB(AABB&& other):
  107. // initialize via default constructor
  108. AABB()
  109. {
  110. swap(*this,other);
  111. }
  112. /// @private
  113. // Seems like there should have been an elegant solution to this using
  114. // the copy-swap idiom above:
  115. IGL_INLINE void clear()
  116. {
  117. m_primitive = -1;
  118. m_box = Eigen::AlignedBox<Scalar,DIM>();
  119. delete m_left;
  120. m_left = nullptr;
  121. delete m_right;
  122. m_right = nullptr;
  123. // Tell my parent I'm dead
  124. if(m_parent)
  125. {
  126. if(m_parent->m_left == this)
  127. {
  128. m_parent->m_left = nullptr;
  129. }else if(m_parent->m_right == this)
  130. {
  131. m_parent->m_right = nullptr;
  132. }else
  133. {
  134. assert(false && "I'm not my parent's child");
  135. }
  136. auto * grandparent = m_parent->m_parent;
  137. if(grandparent)
  138. {
  139. // Before
  140. // grandparent
  141. // ╱ ╲
  142. // parent pibling
  143. // ╱ ╲
  144. // sibling this
  145. //
  146. // After
  147. // grandparent
  148. // ╱ ╲
  149. // sibling® pibling
  150. }else
  151. {
  152. // Before
  153. // parent=root
  154. // ╱ ╲
  155. // sibling this
  156. //
  157. // After
  158. // grandparent
  159. // ╱ ╲
  160. // sibling® pibling
  161. }
  162. }
  163. // Now my parent is dead to me.
  164. m_parent = nullptr;
  165. }
  166. /// @private
  167. ~AABB()
  168. {
  169. clear();
  170. }
  171. /// Return whether at leaf node
  172. IGL_INLINE bool is_leaf() const;
  173. /// Return whether at root node
  174. IGL_INLINE bool is_root() const;
  175. /// Return the root node of this node's tree by following its parent
  176. IGL_INLINE AABB<DerivedV,DIM>* root() const;
  177. IGL_INLINE AABB<DerivedV,DIM>* detach();
  178. IGL_INLINE void refit_lineage();
  179. /// Get a vector of leaves indexed by their m_primitive id (these better
  180. /// be non-negative and tightly packed.
  181. /// @param[in] m number of leaves/elements (Ele.rows())
  182. /// @returns leaves m list of pointers to leaves
  183. IGL_INLINE std::vector<AABB<DerivedV,DIM>*> gather_leaves(const int m);
  184. /// \overload where m is the max m_primitive id in the tree.
  185. IGL_INLINE std::vector<AABB<DerivedV,DIM>*> gather_leaves();
  186. /// Pad leaves by `pad` in each dimension
  187. /// @param[in] pad padding amount
  188. /// @param[in] polish_rotate_passes number of passes to polish rotations
  189. /// @returns pointer to (potentially new) root
  190. IGL_INLINE AABB<DerivedV,DIM>* pad(
  191. const std::vector<AABB<DerivedV,DIM>*> & leaves,
  192. const Scalar pad,
  193. const int polish_rotate_passes=0);
  194. /// @returns `this` if no update was needed, otherwise returns pointer to
  195. /// (potentially new) root
  196. ///
  197. /// Example:
  198. /// ```cpp
  199. /// auto * up = leaf->update(new_box);
  200. /// if(up != leaf)
  201. /// {
  202. /// tree = up->root();
  203. /// }else
  204. /// {
  205. /// printf("no update occurred\n");
  206. /// }
  207. ///
  208. /// // or simply
  209. /// tree = leaf->update(new_box)->root();
  210. /// ```
  211. IGL_INLINE AABB<DerivedV,DIM>* update(
  212. const Eigen::AlignedBox<Scalar,DIM> & new_box,
  213. const Scalar pad=0);
  214. /// Insert a (probably a leaf) AABB `other` into this AABB tree. If
  215. /// `other`'s box is contained in this AABB's box then insert it as a child recursively.
  216. ///
  217. /// If `other`'s box is not contained in this AABB's box then insert it as a
  218. /// sibling.
  219. ///
  220. /// It's a very good idea to call either `rotate` (faster, less good) or `rotate_lineage` (slower, better)
  221. /// after insertion. Rotating continues to improve the tree's quality so
  222. /// after doing a bunch of insertions you might even consider calling
  223. /// `rotate` on all nodes.
  224. ///
  225. /// `insert` attempts to minimize total internal surface area. Where as
  226. /// `init` is top-down and splits boxes based on the median along the
  227. /// longest dimension. When initializing a tree, `init` seems to result in
  228. /// great trees (small height and small total internal surface area).
  229. ///
  230. /// @param[in] other pointer to another AABB node
  231. /// @returns pointer to the parent of `other` or `other` itself. This
  232. /// could be == to a `new`ly created internal node or to `other` if
  233. /// `this==other`. Calling ->root() on this returned node will give you
  234. /// the root of the tree.
  235. ///
  236. /// ##### Example
  237. ///
  238. /// ```cpp
  239. /// // Create a tree (use pointer to track changes to root)
  240. /// auto * tree = new igl::AABB<DerivedV,3>::AABB();
  241. /// // Fill the tree (e.g., using ->init())
  242. /// …
  243. /// // Create a new leafe node
  244. /// auto * leaf = new igl::AABB<DerivedV,3>::AABB();
  245. /// // Fill the leaf node with a primitive and box
  246. /// …
  247. /// // Insert into the tree and find the possibly new root
  248. /// tree = tree->insert(leaf)->root();
  249. /// ```
  250. IGL_INLINE AABB<DerivedV,DIM>* insert(AABB * other);
  251. /// Insert `other` as a sibling to `this` by creating a new internal node
  252. /// to be their shared parent.
  253. ///
  254. /// Before
  255. /// parent
  256. /// ╱ ╲
  257. /// this(C) sibling
  258. /// ╱ ╲
  259. /// left right
  260. ///
  261. /// After
  262. /// parent
  263. /// ╱ ╲
  264. /// newbie sibling
  265. /// ╱ ╲
  266. /// this other
  267. /// ╱ ╲
  268. /// left right
  269. ///
  270. ///
  271. /// @param[in] other pointer to another AABB node
  272. /// @returns pointer to the new shared parent.
  273. IGL_INLINE AABB<DerivedV,DIM>* insert_as_sibling(AABB * other);
  274. /// Try to swap this node with its close relatives if it will decrease
  275. /// total internal surface area.
  276. ///
  277. ///
  278. /// grandparent
  279. /// ╱ ╲
  280. /// parent pibling°
  281. /// ╱ ╲ ╱ ╲
  282. /// sibling this cuz1° cuz2°
  283. /// ╱ ╲
  284. /// nib1° nib2°
  285. ///
  286. /// °Swap Candidates
  287. ///
  288. /// @param[in] dry_run if true then don't actually swap
  289. /// @return[in] the change in total internal surface area, 0 if no
  290. /// improvement and rotate won't be carried out.
  291. IGL_INLINE Scalar rotate(const bool dry_run = false);
  292. /// Try to swap this node with its cousins if it will decrease
  293. /// total internal surface area.
  294. ///
  295. /// @param[in] dry_run if true then don't actually swap
  296. /// @return[in] the change in total internal surface area, 0 if no
  297. /// improvement and rotate won't be carried out.
  298. ///
  299. /// Before
  300. /// grandparent
  301. /// ╱ ╲
  302. /// parent pibling
  303. /// ╱ ╲ ╱ ╲
  304. /// sibling this cuz1 cuz2
  305. ///
  306. ///
  307. /// Candidates
  308. /// grandparent
  309. /// ╱ ╲
  310. /// parent pibling
  311. /// ╱ ╲ ╱ ╲
  312. /// sibling cuz1 this cuz2
  313. ///
  314. /// Or
  315. /// grandparent
  316. /// ╱ ╲
  317. /// parent pibling
  318. /// ╱ ╲ ╱ ╲
  319. /// sibling cuz2 cuz1 this
  320. IGL_INLINE Scalar rotate_across(const bool dry_run = false);
  321. /// Try to swap this node with its pibling if it will decrease
  322. /// total internal surface area.
  323. ///
  324. /// @param[in] dry_run if true then don't actually swap
  325. /// @return[in] the change in total internal surface area, 0 if no
  326. /// improvement and rotate won't be carried out.
  327. ///
  328. /// Before
  329. /// grandparent
  330. /// ╱ ╲
  331. /// other parent
  332. /// ╱ ╲
  333. /// this sibling
  334. ///
  335. ///
  336. /// Candidate
  337. /// grandparent
  338. /// ╱ ╲
  339. /// this parent
  340. /// ╱ ╲
  341. /// other sibling
  342. IGL_INLINE Scalar rotate_up(const bool dry_run = false);
  343. /// Try to swap this node with one of its niblings if it will decrease
  344. /// total internal surface area.
  345. ///
  346. /// @param[in] dry_run if true then don't actually swap
  347. /// @return[in] the change in total internal surface area, 0 if no
  348. /// improvement and rotate won't be carried out.
  349. ///
  350. /// Before
  351. /// parent
  352. /// ╱ ╲
  353. /// this sibling
  354. /// ╱ ╲
  355. /// left right
  356. ///
  357. ///
  358. /// Candidates
  359. /// parent
  360. /// ╱ ╲
  361. /// left sibling
  362. /// ╱ ╲
  363. /// this right
  364. ///
  365. /// Or
  366. ///
  367. /// parent
  368. /// ╱ ╲
  369. /// right sibling
  370. /// ╱ ╲
  371. /// left this
  372. IGL_INLINE Scalar rotate_down(const bool dry_run = false);
  373. /// "Rotate" (swap) `reining` with `challenger`.
  374. ///
  375. /// Before
  376. /// grandparent
  377. /// ╱ ╲
  378. /// reining parent
  379. /// ╱ ╲
  380. /// challenger sibling
  381. ///
  382. ///
  383. /// Candidate
  384. /// grandparent
  385. /// ╱ ╲
  386. /// challenger parent
  387. /// ╱ ╲
  388. /// reining sibling
  389. /// @param[in] reining pointer to AABB node to be rotated
  390. /// @param[in] grandparent pointer to challenger's grandparent
  391. /// @param[in] parent pointer to challenger's parent
  392. /// @param[in] challenger pointer to AABB node to be rotated
  393. /// @param[in] sibling pointer to challenger's sibling
  394. /// @returns true only if rotation was possible and successfully carried
  395. /// out.
  396. static IGL_INLINE Scalar rotate_up(
  397. const bool dry_run,
  398. AABB<DerivedV,DIM>* reining,
  399. AABB<DerivedV,DIM>* grandparent,
  400. AABB<DerivedV,DIM>* parent,
  401. AABB<DerivedV,DIM>* challenger,
  402. AABB<DerivedV,DIM>* sibling);
  403. // Should this be a static function with an argument?
  404. IGL_INLINE void rotate_lineage();
  405. /// Number of nodes contained in subtree (is it?)
  406. ///
  407. /// \note At best, this function has a dubious name. This is really an
  408. /// internal helper function for the serialization.
  409. ///
  410. /// \see size()
  411. ///
  412. /// @return Number of elements m then total tree size should be 2*h where h is
  413. /// the deepest depth 2^ceil(log(#Ele*2-1))
  414. IGL_INLINE int subtree_size() const;
  415. /// @param[in] box query box
  416. /// @param[in,out] leaves list of leaves to append to
  417. IGL_INLINE bool append_intersecting_leaves(
  418. const Eigen::AlignedBox<Scalar,DIM> & box,
  419. std::vector<const AABB<DerivedV,DIM>*> & leaves) const;
  420. /// Compute sum of surface area of all internal (non-root, non-leaf) boxes
  421. IGL_INLINE typename DerivedV::Scalar internal_surface_area() const;
  422. /// Validate the subtree under this node by running a bunch of assertions.
  423. /// Does nothing when not in debug mode
  424. IGL_INLINE void validate() const;
  425. /// print the memory addresses of the tree in a somewhat legible way
  426. IGL_INLINE void print(const int depth = 0) const;
  427. /// @returns Actual size of tree. Total number of nodes in tree. A singleton root
  428. /// has size 1.
  429. ///
  430. /// \see subtree_size
  431. IGL_INLINE int size() const;
  432. /// @returns Height of the tree. A singleton root has height 1.
  433. IGL_INLINE int height() const;
  434. private:
  435. /// If new distance (sqr_d_candidate) is less than current distance
  436. /// (sqr_d), then update this distance and its associated values
  437. /// _in-place_:
  438. ///
  439. /// @param[in] p dim-long query point (only used in DEBUG mode)
  440. /// @param[in] sqr_d candidate minimum distance for this query, see
  441. /// output
  442. /// @param[in] i candidate index into Ele of closest point, see output
  443. /// @param[in] c dim-long candidate closest point, see output
  444. /// @param[in] sqr_d current minimum distance for this query, see output
  445. /// @param[in] i current index into Ele of closest point, see output
  446. /// @param[in] c dim-long current closest point, see output
  447. /// @param[out] sqr_d minimum of initial value and squared distance to
  448. /// this primitive
  449. /// @param[out] i possibly updated index into Ele of closest point
  450. /// @param[out] c dim-long possibly updated closest point
  451. IGL_INLINE void set_min(
  452. const RowVectorDIMS & p,
  453. const Scalar sqr_d_candidate,
  454. const int & i_candidate,
  455. const RowVectorDIMS & c_candidate,
  456. Scalar & sqr_d,
  457. int & i,
  458. Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
  459. public:
  460. ///////////////////////////////////////////////////////////////////////////////
  461. // Templated member functions
  462. ///////////////////////////////////////////////////////////////////////////////
  463. /// Build an Axis-Aligned Bounding Box tree for a given mesh and given
  464. /// serialization of a previous AABB tree.
  465. ///
  466. /// @param[in] V #V by dim list of mesh vertex positions.
  467. /// @param[in] Ele #Ele by dim+1 list of mesh indices into #V.
  468. /// @param[in] bb_mins max_tree by dim list of bounding box min corner
  469. /// positions
  470. /// @param[in] bb_maxs max_tree by dim list of bounding box max corner
  471. /// positions
  472. /// @param[in] elements max_tree list of element or (not leaf id) indices
  473. /// into Ele
  474. /// @param[in] i recursive call index {0}
  475. template <
  476. typename DerivedEle,
  477. typename Derivedbb_mins,
  478. typename Derivedbb_maxs,
  479. typename Derivedelements>
  480. IGL_INLINE void init(
  481. const Eigen::MatrixBase<DerivedV> & V,
  482. const Eigen::MatrixBase<DerivedEle> & Ele,
  483. const Eigen::MatrixBase<Derivedbb_mins> & bb_mins,
  484. const Eigen::MatrixBase<Derivedbb_maxs> & bb_maxs,
  485. const Eigen::MatrixBase<Derivedelements> & elements,
  486. const int i = 0);
  487. /// Build an Axis-Aligned Bounding Box tree for a given mesh and given
  488. /// serialization of a previous AABB tree.
  489. ///
  490. /// @param[in] V #V by dim list of mesh vertex positions.
  491. /// @param[in] Ele #Ele by dim+1 list of mesh indices into #V.
  492. template <typename DerivedEle>
  493. IGL_INLINE void init(
  494. const Eigen::MatrixBase<DerivedV> & V,
  495. const Eigen::MatrixBase<DerivedEle> & Ele);
  496. /// Build an Axis-Aligned Bounding Box tree for a given mesh.
  497. ///
  498. /// @param[in] V #V by dim list of mesh vertex positions.
  499. /// @param[in] Ele #Ele by dim+1 list of mesh indices into #V.
  500. /// @param[in] SI #Ele by dim list revealing for each coordinate where
  501. /// Ele's barycenters would be sorted: SI(e,d) = i --> the dth
  502. /// coordinate of the barycenter of the eth element would be placed at
  503. /// position i in a sorted list.
  504. /// @param[in] I #I list of indices into Ele of elements to include (for
  505. /// recursive calls)
  506. ///
  507. template <typename DerivedEle, typename DerivedSI, typename DerivedI>
  508. IGL_INLINE void init(
  509. const Eigen::MatrixBase<DerivedV> & V,
  510. const Eigen::MatrixBase<DerivedEle> & Ele,
  511. const Eigen::MatrixBase<DerivedSI> & SI,
  512. const Eigen::MatrixBase<DerivedI>& I);
  513. /// @returns `this` if no update was needed, otherwise returns pointer to
  514. /// (potentially new) root
  515. template <typename DerivedEle>
  516. IGL_INLINE AABB<DerivedV,DIM>* update_primitive(
  517. const Eigen::MatrixBase<DerivedV> & V,
  518. const Eigen::MatrixBase<DerivedEle> & Ele,
  519. const Scalar pad=0);
  520. /// Find the indices of elements containing given point: this makes sense
  521. /// when Ele is a co-dimension 0 simplex (tets in 3D, triangles in 2D).
  522. ///
  523. /// @param[in] V #V by dim list of mesh vertex positions. **Should be
  524. /// same as used to construct mesh.**
  525. /// @param[in] Ele #Ele by dim+1 list of mesh indices into #V. **Should
  526. /// be same as used to construct mesh.**
  527. /// @param[in] q dim row-vector query position
  528. /// @param[in] first whether to only return first element containing q
  529. /// @return list of indices of elements containing q
  530. template <typename DerivedEle, typename Derivedq>
  531. IGL_INLINE std::vector<int> find(
  532. const Eigen::MatrixBase<DerivedV> & V,
  533. const Eigen::MatrixBase<DerivedEle> & Ele,
  534. const Eigen::MatrixBase<Derivedq> & q,
  535. const bool first=false) const;
  536. /// Serialize this class into 3 arrays (so we can pass it pack to matlab)
  537. ///
  538. /// @param[out] bb_mins max_tree by dim list of bounding box min corner
  539. /// positions
  540. /// @param[out] bb_maxs max_tree by dim list of bounding box max corner
  541. /// positions
  542. /// @param[out] elements max_tree list of element or (not leaf id)
  543. /// indices into Ele
  544. /// @param[in] i recursive call index into these arrays {0}
  545. template <
  546. typename Derivedbb_mins,
  547. typename Derivedbb_maxs,
  548. typename Derivedelements>
  549. IGL_INLINE void serialize(
  550. Eigen::PlainObjectBase<Derivedbb_mins> & bb_mins,
  551. Eigen::PlainObjectBase<Derivedbb_maxs> & bb_maxs,
  552. Eigen::PlainObjectBase<Derivedelements> & elements,
  553. const int i = 0) const;
  554. /// Compute squared distance to a query point
  555. ///
  556. /// @param[in] V #V by dim list of vertex positions
  557. /// @param[in] Ele #Ele by dim list of simplex indices
  558. /// @param[in] p dim-long query point
  559. /// @param[out] i facet index corresponding to smallest distances
  560. /// @param[out] c closest point
  561. /// @return squared distance
  562. ///
  563. /// \pre Currently assumes Elements are triangles regardless of
  564. /// dimension.
  565. template <typename DerivedEle>
  566. IGL_INLINE Scalar squared_distance(
  567. const Eigen::MatrixBase<DerivedV> & V,
  568. const Eigen::MatrixBase<DerivedEle> & Ele,
  569. const RowVectorDIMS & p,
  570. int & i,
  571. Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
  572. /// Compute squared distance to a query point if within `low_sqr_d` and
  573. /// `up_sqr_d`.
  574. ///
  575. /// @param[in] V #V by dim list of vertex positions
  576. /// @param[in] Ele #Ele by dim list of simplex indices
  577. /// @param[in] p dim-long query point
  578. /// @param[in] low_sqr_d lower bound on squared distance, specified
  579. /// maximum squared distance
  580. /// @param[in] up_sqr_d current upper bounded on squared distance,
  581. /// current minimum squared distance (only consider distances less than
  582. /// this), see output.
  583. /// @param[out] i facet index corresponding to smallest distances
  584. /// @param[out] c closest point
  585. /// @return squared distance
  586. ///
  587. /// \pre currently assumes Elements are triangles regardless of
  588. /// dimension.
  589. template <typename DerivedEle>
  590. IGL_INLINE Scalar squared_distance(
  591. const Eigen::MatrixBase<DerivedV> & V,
  592. const Eigen::MatrixBase<DerivedEle> & Ele,
  593. const RowVectorDIMS & p,
  594. const Scalar low_sqr_d,
  595. const Scalar up_sqr_d,
  596. int & i,
  597. Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
  598. /// Compute squared distance to a query point (default `low_sqr_d`)
  599. ///
  600. /// @param[in] V #V by dim list of vertex positions
  601. /// @param[in] Ele #Ele by dim list of simplex indices
  602. /// @param[in] p dim-long query point
  603. /// @param[in] up_sqr_d current upper bounded on squared distance,
  604. /// current minimum squared distance (only consider distances less than
  605. /// this), see output.
  606. /// @param[out] i facet index corresponding to smallest distances
  607. /// @param[out] c closest point
  608. /// @return squared distance
  609. ///
  610. template <typename DerivedEle>
  611. IGL_INLINE Scalar squared_distance(
  612. const Eigen::MatrixBase<DerivedV> & V,
  613. const Eigen::MatrixBase<DerivedEle> & Ele,
  614. const RowVectorDIMS & p,
  615. const Scalar up_sqr_d,
  616. int & i,
  617. Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
  618. /// Intersect a ray with the mesh return all hits
  619. ///
  620. /// @param[in] V #V by dim list of vertex positions
  621. /// @param[in] Ele #Ele by dim list of simplex indices
  622. /// @param[in] origin dim-long ray origin
  623. /// @param[in] dir dim-long ray direction
  624. /// @param[out] hits list of hits
  625. /// @return true if any hits
  626. template <typename DerivedEle>
  627. IGL_INLINE bool intersect_ray(
  628. const Eigen::MatrixBase<DerivedV> & V,
  629. const Eigen::MatrixBase<DerivedEle> & Ele,
  630. const RowVectorDIMS & origin,
  631. const RowVectorDIMS & dir,
  632. std::vector<igl::Hit<typename DerivedV::Scalar>> & hits) const;
  633. /// Intersect a ray with the mesh return first hit
  634. ///
  635. /// @param[in] V #V by dim list of vertex positions
  636. /// @param[in] Ele #Ele by dim list of simplex indices
  637. /// @param[in] origin dim-long ray origin
  638. /// @param[in] dir dim-long ray direction
  639. /// @param[out] hit first hit
  640. /// @return true if any hit
  641. template <typename DerivedEle>
  642. IGL_INLINE bool intersect_ray(
  643. const Eigen::MatrixBase<DerivedV> & V,
  644. const Eigen::MatrixBase<DerivedEle> & Ele,
  645. const RowVectorDIMS & origin,
  646. const RowVectorDIMS & dir,
  647. igl::Hit<typename DerivedV::Scalar> & hit) const;
  648. /// Intersect a ray with the mesh return first hit farther than `min_t`
  649. ///
  650. /// @param[in] V #V by dim list of vertex positions
  651. /// @param[in] Ele #Ele by dim list of simplex indices
  652. /// @param[in] origin dim-long ray origin
  653. /// @param[in] dir dim-long ray direction
  654. /// @param[in] min_t minimum t value to consider
  655. /// @param[out] hit first hit
  656. /// @return true if any hit
  657. template <typename DerivedEle>
  658. IGL_INLINE bool intersect_ray(
  659. const Eigen::MatrixBase<DerivedV> & V,
  660. const Eigen::MatrixBase<DerivedEle> & Ele,
  661. const RowVectorDIMS & origin,
  662. const RowVectorDIMS & dir,
  663. const Scalar min_t,
  664. igl::Hit<typename DerivedV::Scalar> & hit) const;
  665. /// Intersect a rays with the mesh return first hit for each
  666. ///
  667. /// @param[in] V #V by dim list of vertex positions
  668. /// @param[in] Ele #Ele by dim list of simplex indices
  669. /// @param[in] origin #ray by dim+1 list of ray origins
  670. /// @param[in] dir #ray by dim list of ray directions
  671. /// @param[in] min_t minimum t value to consider
  672. /// @param[out] I #ray list of indices into Ele of closest primitives
  673. /// (-1 indicates no hit)
  674. /// @param[out] T #ray list of t values (nan indicates no hit)
  675. /// @param[out] UV #ray by dim list of barycentric coordinates
  676. template <
  677. typename DerivedEle,
  678. typename DerivedOrigin,
  679. typename DerivedDir,
  680. typename DerivedI,
  681. typename DerivedT,
  682. typename DerivedUV>
  683. IGL_INLINE void intersect_ray(
  684. const Eigen::MatrixBase<DerivedV> & V,
  685. const Eigen::MatrixBase<DerivedEle> & Ele,
  686. const Eigen::MatrixBase<DerivedOrigin> & origin,
  687. const Eigen::MatrixBase<DerivedDir> & dir,
  688. const Scalar min_t,
  689. Eigen::PlainObjectBase<DerivedI> & I,
  690. Eigen::PlainObjectBase<DerivedT> & T,
  691. Eigen::PlainObjectBase<DerivedUV> & UV);
  692. template <
  693. typename DerivedEle,
  694. typename DerivedOrigin,
  695. typename DerivedDir>
  696. IGL_INLINE void intersect_ray(
  697. const Eigen::MatrixBase<DerivedV> & V,
  698. const Eigen::MatrixBase<DerivedEle> & Ele,
  699. const Eigen::MatrixBase<DerivedOrigin> & origin,
  700. const Eigen::MatrixBase<DerivedDir> & dir,
  701. std::vector<std::vector<igl::Hit<typename DerivedV::Scalar>>> & hits);
  702. /// Compute the squared distance from all query points in P to the
  703. /// _closest_ points on the primitives stored in the AABB hierarchy for
  704. /// the mesh (V,Ele).
  705. ///
  706. /// @param[in] V #V by dim list of vertex positions
  707. /// @param[in] Ele #Ele by dim list of simplex indices
  708. /// @param[in] P #P by dim list of query points
  709. /// @param[out] sqrD #P list of squared distances
  710. /// @param[out] I #P list of indices into Ele of closest primitives
  711. /// @param[out] C #P by dim list of closest points
  712. template <
  713. typename DerivedEle,
  714. typename DerivedP,
  715. typename DerivedsqrD,
  716. typename DerivedI,
  717. typename DerivedC>
  718. IGL_INLINE void squared_distance(
  719. const Eigen::MatrixBase<DerivedV> & V,
  720. const Eigen::MatrixBase<DerivedEle> & Ele,
  721. const Eigen::MatrixBase<DerivedP> & P,
  722. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  723. Eigen::PlainObjectBase<DerivedI> & I,
  724. Eigen::PlainObjectBase<DerivedC> & C) const;
  725. /// Compute the squared distance from all query points in P already stored
  726. /// in its own AABB hierarchy to the _closest_ points on the primitives
  727. /// stored in the AABB hierarchy for the mesh (V,Ele).
  728. ///
  729. /// @param[in] V #V by dim list of vertex positions
  730. /// @param[in] Ele #Ele by dim list of simplex indices
  731. /// @param[in] other AABB hierarchy of another set of primitives (must be points)
  732. /// @param[in] other_V #other_V by dim list of query points
  733. /// @param[in] other_Ele #other_Ele by ss list of simplex indices into other_V
  734. /// (must be simple list of points: ss == 1)
  735. /// @param[out] sqrD #P list of squared distances
  736. /// @param[out] I #P list of indices into Ele of closest primitives
  737. /// @param[out] C #P by dim list of closest points
  738. template <
  739. typename DerivedEle,
  740. typename Derivedother_V,
  741. typename Derivedother_Ele,
  742. typename DerivedsqrD,
  743. typename DerivedI,
  744. typename DerivedC>
  745. IGL_INLINE void squared_distance(
  746. const Eigen::MatrixBase<DerivedV> & V,
  747. const Eigen::MatrixBase<DerivedEle> & Ele,
  748. const AABB<Derivedother_V,DIM> & other,
  749. const Eigen::MatrixBase<Derivedother_V> & other_V,
  750. const Eigen::MatrixBase<Derivedother_Ele> & other_Ele,
  751. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  752. Eigen::PlainObjectBase<DerivedI> & I,
  753. Eigen::PlainObjectBase<DerivedC> & C) const;
  754. private:
  755. template <
  756. typename DerivedEle,
  757. typename Derivedother_V,
  758. typename Derivedother_Ele,
  759. typename DerivedsqrD,
  760. typename DerivedI,
  761. typename DerivedC>
  762. IGL_INLINE Scalar squared_distance_helper(
  763. const Eigen::MatrixBase<DerivedV> & V,
  764. const Eigen::MatrixBase<DerivedEle> & Ele,
  765. const AABB<Derivedother_V,DIM> * other,
  766. const Eigen::MatrixBase<Derivedother_V> & other_V,
  767. const Eigen::MatrixBase<Derivedother_Ele>& other_Ele,
  768. const Scalar up_sqr_d,
  769. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  770. Eigen::PlainObjectBase<DerivedI> & I,
  771. Eigen::PlainObjectBase<DerivedC> & C) const;
  772. // Compute the squared distance to the primitive in this node: assumes
  773. // that this is indeed a leaf node.
  774. //
  775. // Inputs:
  776. // V #V by dim list of vertex positions
  777. // Ele #Ele by dim list of simplex indices
  778. // p dim-long query point
  779. // sqr_d current minimum distance for this query, see output
  780. // i current index into Ele of closest point, see output
  781. // c dim-long current closest point, see output
  782. // Outputs:
  783. // sqr_d minimum of initial value and squared distance to this
  784. // primitive
  785. // i possibly updated index into Ele of closest point
  786. // c dim-long possibly updated closest point
  787. template <typename DerivedEle>
  788. IGL_INLINE void leaf_squared_distance(
  789. const Eigen::MatrixBase<DerivedV> & V,
  790. const Eigen::MatrixBase<DerivedEle> & Ele,
  791. const RowVectorDIMS & p,
  792. const Scalar low_sqr_d,
  793. Scalar & sqr_d,
  794. int & i,
  795. Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
  796. // Default low_sqr_d
  797. template <typename DerivedEle>
  798. IGL_INLINE void leaf_squared_distance(
  799. const Eigen::MatrixBase<DerivedV> & V,
  800. const Eigen::MatrixBase<DerivedEle> & Ele,
  801. const RowVectorDIMS & p,
  802. Scalar & sqr_d,
  803. int & i,
  804. Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
  805. /// Intersect a ray with the mesh return all hits
  806. ///
  807. /// @param[in] V #V by dim list of vertex positions
  808. /// @param[in] Ele #Ele by dim list of simplex indices
  809. /// @param[in] origin dim-long ray origin
  810. /// @param[in] dir dim-long ray direction
  811. /// @param[out] hits list of hits
  812. /// @return true if any hits
  813. template <typename DerivedEle>
  814. IGL_INLINE bool intersect_ray_opt(
  815. const Eigen::MatrixBase<DerivedV> & V,
  816. const Eigen::MatrixBase<DerivedEle> & Ele,
  817. const RowVectorDIMS & origin,
  818. const RowVectorDIMS & dir,
  819. const RowVectorDIMS & inv_dir,
  820. const RowVectorDIMS & inv_dir_pad,
  821. std::vector<igl::Hit<typename DerivedV::Scalar>> & hits) const;
  822. /// Intersect a ray with the mesh return first hit farther than `min_t`
  823. ///
  824. /// @param[in] V #V by dim list of vertex positions
  825. /// @param[in] Ele #Ele by dim list of simplex indices
  826. /// @param[in] origin dim-long ray origin
  827. /// @param[in] dir dim-long ray direction
  828. /// @param[in] min_t minimum t value to consider
  829. /// @param[out] hit first hit
  830. /// @return true if any hit
  831. template <typename DerivedEle>
  832. IGL_INLINE bool intersect_ray_opt(
  833. const Eigen::MatrixBase<DerivedV> & V,
  834. const Eigen::MatrixBase<DerivedEle> & Ele,
  835. const RowVectorDIMS & origin,
  836. const RowVectorDIMS & dir,
  837. const RowVectorDIMS & inv_dir,
  838. const RowVectorDIMS & inv_dir_pad,
  839. const Scalar min_t,
  840. igl::Hit<typename DerivedV::Scalar> & hit) const;
  841. public:
  842. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  843. };
  844. }
  845. #ifndef IGL_STATIC_LIBRARY
  846. # include "AABB.cpp"
  847. #endif
  848. #endif