AABB.cpp 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 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. #include "AABB.h"
  9. #include "EPS.h"
  10. #include "barycenter.h"
  11. #include "colon.h"
  12. #include "doublearea.h"
  13. #include "increment_ulp.h"
  14. #include "point_simplex_squared_distance.h"
  15. #include "project_to_line_segment.h"
  16. #include "sort.h"
  17. #include "volume.h"
  18. #include "ray_box_intersect.h"
  19. #include "parallel_for.h"
  20. #include "ray_mesh_intersect.h"
  21. #include "box_surface_area.h"
  22. #include "pad_box.h"
  23. #include <iostream>
  24. #include <iomanip>
  25. #include <limits>
  26. #include <list>
  27. #include <queue>
  28. #include <stack>
  29. #include <string>
  30. #include <stdio.h>
  31. // This would be so much better with C++17 if constexpr
  32. namespace
  33. {
  34. template <
  35. typename DerivedV,
  36. typename DerivedEle,
  37. typename Derivedq,
  38. int DIM>
  39. struct AABB_all_positive_barycentric_coordinates_helper;
  40. template <
  41. typename DerivedV,
  42. typename DerivedEle,
  43. typename Derivedq>
  44. struct AABB_all_positive_barycentric_coordinates_helper<
  45. DerivedV,
  46. DerivedEle,
  47. Derivedq,
  48. 2>
  49. {
  50. static inline bool compute(
  51. const Eigen::MatrixBase<DerivedV> & V,
  52. const Eigen::MatrixBase<DerivedEle> & Ele,
  53. const int primitive,
  54. const Eigen::MatrixBase<Derivedq> & q)
  55. {
  56. using namespace igl;
  57. using Scalar = typename DerivedV::Scalar;
  58. const Scalar epsilon = igl::EPS<Scalar>();
  59. static_assert(
  60. DerivedV::ColsAtCompileTime == 2 ||
  61. DerivedV::ColsAtCompileTime == Eigen::Dynamic,
  62. "V should be 2D");
  63. static_assert(
  64. Derivedq::ColsAtCompileTime == 2 ||
  65. Derivedq::ColsAtCompileTime == Eigen::Dynamic,
  66. "q should be 2D");
  67. // Barycentric coordinates
  68. typedef Eigen::Matrix<Scalar,2,1> Vector2S;
  69. const Vector2S V1 = V.row(Ele(primitive,0));
  70. const Vector2S V2 = V.row(Ele(primitive,1));
  71. const Vector2S V3 = V.row(Ele(primitive,2));
  72. // Hack for now to keep templates simple. If becomes bottleneck
  73. // consider using std::enable_if_t
  74. const Vector2S q2 = q.head(2);
  75. Scalar a1 = doublearea_single(V1,V2,q2);
  76. Scalar a2 = doublearea_single(V2,V3,q2);
  77. Scalar a3 = doublearea_single(V3,V1,q2);
  78. // Normalization is important for correcting magnitude near epsilon
  79. Scalar sum = a1+a2+a3;
  80. a1 /= sum;
  81. a2 /= sum;
  82. a3 /= sum;
  83. return a1>=-epsilon && a2>=-epsilon && a3>=-epsilon;
  84. }
  85. };
  86. template <
  87. typename DerivedV,
  88. typename DerivedEle,
  89. typename Derivedq>
  90. struct AABB_all_positive_barycentric_coordinates_helper<
  91. DerivedV,
  92. DerivedEle,
  93. Derivedq,
  94. 3>
  95. {
  96. static inline bool compute(
  97. const Eigen::MatrixBase<DerivedV> & V,
  98. const Eigen::MatrixBase<DerivedEle> & Ele,
  99. const int primitive,
  100. const Eigen::MatrixBase<Derivedq> & q)
  101. {
  102. using namespace igl;
  103. using Scalar = typename DerivedV::Scalar;
  104. const Scalar epsilon = igl::EPS<Scalar>();
  105. static_assert(
  106. DerivedV::ColsAtCompileTime == 3 ||
  107. DerivedV::ColsAtCompileTime == Eigen::Dynamic,
  108. "V should be 2D");
  109. static_assert(
  110. Derivedq::ColsAtCompileTime == 3 ||
  111. Derivedq::ColsAtCompileTime == Eigen::Dynamic,
  112. "q should be 2D");
  113. // Barycentric coordinates
  114. typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
  115. const RowVector3S V1 = V.row(Ele(primitive,0));
  116. const RowVector3S V2 = V.row(Ele(primitive,1));
  117. const RowVector3S V3 = V.row(Ele(primitive,2));
  118. const RowVector3S V4 = V.row(Ele(primitive,3));
  119. Scalar a1 = volume_single(V2,V4,V3,(RowVector3S)q);
  120. Scalar a2 = volume_single(V1,V3,V4,(RowVector3S)q);
  121. Scalar a3 = volume_single(V1,V4,V2,(RowVector3S)q);
  122. Scalar a4 = volume_single(V1,V2,V3,(RowVector3S)q);
  123. Scalar sum = a1+a2+a3+a4;
  124. a1 /= sum;
  125. a2 /= sum;
  126. a3 /= sum;
  127. a4 /= sum;
  128. return a1>=-epsilon && a2>=-epsilon && a3>=-epsilon && a4>=-epsilon;
  129. }
  130. };
  131. }
  132. ///////////////////////////////////////////////////////////////////////////////
  133. // Non-templated member functions
  134. ///////////////////////////////////////////////////////////////////////////////
  135. template <typename DerivedV, int DIM>
  136. IGL_INLINE bool igl::AABB<DerivedV,DIM>::is_leaf() const
  137. {
  138. // This way (rather than `m_primitive != -1` we can have empty leaves
  139. return m_left == nullptr && m_right == nullptr;
  140. }
  141. template <typename DerivedV, int DIM>
  142. IGL_INLINE bool igl::AABB<DerivedV,DIM>::is_root() const
  143. {
  144. return m_parent == nullptr;
  145. }
  146. template <typename DerivedV, int DIM>
  147. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::root() const
  148. {
  149. return (is_root() ? const_cast<igl::AABB<DerivedV,DIM>*>(this) : m_parent->root());
  150. }
  151. template <typename DerivedV, int DIM>
  152. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::detach()
  153. {
  154. if(!this->m_parent)
  155. {
  156. // Before
  157. // ⊘-this
  158. //
  159. // After
  160. // ⊘-this
  161. //
  162. // `this` is the root. It's already detached.
  163. return this;
  164. }
  165. auto * parent = this->m_parent;
  166. assert(parent);
  167. // Detach from parent
  168. this->m_parent = nullptr;
  169. auto * grandparent = parent->m_parent;
  170. auto * sibling = parent->m_left == this ? parent->m_right : parent->m_left;
  171. assert(sibling);
  172. // Before
  173. // grandparent
  174. // ╱
  175. // parent
  176. // ╱ ╲
  177. // sibling this
  178. //
  179. // After
  180. // grandparent
  181. // /
  182. // sibling® ⊘ ☠️ parent☠️
  183. // |
  184. // this
  185. //
  186. // Grandparent is sibling's parent now: works even if parent is root
  187. // (grandparent is null)
  188. sibling->m_parent = grandparent;
  189. // Parent is now parentless and childless (to make clear() happy)
  190. parent->m_parent = nullptr;
  191. parent->m_left = nullptr;
  192. parent->m_right = nullptr;
  193. // Tell grandparent sibling is new child.
  194. if(grandparent)
  195. {
  196. (grandparent->m_left == parent ?
  197. grandparent->m_left : grandparent->m_right) = sibling;
  198. }
  199. // Did your code just crash here? Perhaps it's because you statically
  200. // allocated your tree instead of using `new`. That's not allowed if you're
  201. // going to call dynamic methods like `detach` and `insert`.
  202. //
  203. // This is a design flaw that requires a refactor of igl::AABB to fix.
  204. delete parent;
  205. return sibling;
  206. }
  207. template <typename DerivedV, int DIM>
  208. IGL_INLINE void igl::AABB<DerivedV,DIM>::refit_lineage()
  209. {
  210. const decltype(m_box) old_box = m_box;
  211. if(!is_leaf())
  212. {
  213. m_box.setEmpty();
  214. if(m_left) { m_box.extend(m_left->m_box); }
  215. if(m_right) { m_box.extend(m_right->m_box); }
  216. }
  217. // Q: is box.contains(old_box) ever true?
  218. // H: It's really supposed to be testing whether anything changed. But the
  219. // call patterns for refit_lineage might be only hitting cases where box is always
  220. // smaler than old_box.
  221. if(m_parent && !m_box.contains(old_box)) { m_parent->refit_lineage(); }
  222. }
  223. template <typename DerivedV, int DIM>
  224. IGL_INLINE std::vector<igl::AABB<DerivedV,DIM>*>
  225. igl::AABB<DerivedV,DIM>::gather_leaves(const int m)
  226. {
  227. auto * tree = this;
  228. std::vector<igl::AABB<DerivedV,DIM>*> leaves(m,nullptr);
  229. {
  230. std::vector<igl::AABB<DerivedV,DIM>* > stack;
  231. stack.push_back(tree);
  232. while(!stack.empty())
  233. {
  234. auto * node = stack.back();
  235. stack.pop_back();
  236. if(!node) { continue; }
  237. stack.push_back(node->m_left);
  238. stack.push_back(node->m_right);
  239. if(node->is_leaf())
  240. {
  241. assert(node->m_primitive < m && node->m_primitive >= 0);
  242. leaves[node->m_primitive] = node;
  243. }
  244. }
  245. }
  246. return leaves;
  247. }
  248. template <typename DerivedV, int DIM>
  249. IGL_INLINE std::vector<igl::AABB<DerivedV,DIM>*>
  250. igl::AABB<DerivedV,DIM>::gather_leaves()
  251. {
  252. int max_primitive = -1;
  253. {
  254. std::vector<igl::AABB<DerivedV,DIM>* > stack;
  255. stack.push_back(this);
  256. while(!stack.empty())
  257. {
  258. auto * node = stack.back();
  259. stack.pop_back();
  260. if(!node) { continue; }
  261. stack.push_back(node->m_left);
  262. stack.push_back(node->m_right);
  263. max_primitive = std::max(max_primitive,node->m_primitive);
  264. }
  265. }
  266. return gather_leaves(max_primitive+1);
  267. }
  268. template <typename DerivedV, int DIM>
  269. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::pad(
  270. const std::vector<igl::AABB<DerivedV,DIM>*> & leaves,
  271. const igl::AABB<DerivedV,DIM>::Scalar pad,
  272. const int polish_rotate_passes)
  273. {
  274. // Will get reset to root below anyway. This does _not_ operate on subtrees.
  275. auto * tree = this->root();
  276. for(auto * leaf : leaves)
  277. {
  278. assert(leaf);
  279. auto * sibling = leaf->detach();
  280. tree = sibling->root();
  281. // Refit near where leaf used to be since it might move far away.
  282. sibling->refit_lineage();
  283. pad_box(pad,leaf->m_box);
  284. tree = tree->insert(leaf)->root();
  285. // Will potentially reach "above" `this`
  286. leaf->refit_lineage();
  287. leaf->rotate_lineage();
  288. }
  289. for(int pass = 0;pass<polish_rotate_passes;pass++)
  290. {
  291. for(auto * leaf : leaves)
  292. {
  293. assert(leaf);
  294. leaf->rotate_lineage();
  295. }
  296. }
  297. // `this` may have been deleted (during `detach` above). Return (possibly new)
  298. // root.
  299. return tree->root();
  300. }
  301. template <typename DerivedV, int DIM>
  302. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::update(
  303. const Eigen::AlignedBox<Scalar,DIM> & new_box,
  304. const Scalar pad)
  305. {
  306. auto * leaf = this;
  307. if(leaf->m_box.contains(new_box)) { return leaf; }
  308. leaf->m_box = new_box;
  309. pad_box(pad,leaf->m_box);
  310. assert(leaf);
  311. auto * sibling = leaf->detach();
  312. auto * tree = sibling->root();
  313. tree = tree->insert(leaf)->root();
  314. leaf->refit_lineage();
  315. leaf->rotate_lineage();
  316. return this->root();
  317. }
  318. template <typename DerivedV, int DIM>
  319. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::insert_as_sibling(AABB * other)
  320. {
  321. // Before
  322. // parent
  323. // |
  324. // this(C)
  325. // ╱ ╲
  326. // left right
  327. //
  328. // After
  329. // parent
  330. // |
  331. // newbie
  332. // ╱ ╲
  333. // this other
  334. // ╱ ╲
  335. // left right
  336. //
  337. auto * parent = this->m_parent;
  338. AABB<DerivedV,DIM> * newbie = new AABB<DerivedV,DIM>();
  339. newbie->m_parent = parent;
  340. newbie->m_left = this;
  341. newbie->m_right = other;
  342. newbie->m_box.extend(this->m_box);
  343. newbie->m_box.extend(other->m_box);
  344. newbie->m_primitive = -1;
  345. this->m_parent = newbie;
  346. other->m_parent = newbie;
  347. if(parent)
  348. {
  349. parent->m_left == this ? parent->m_left = newbie : parent->m_right = newbie;
  350. assert(parent->m_box.contains(newbie->m_box));
  351. }
  352. return newbie;
  353. }
  354. template <typename DerivedV, int DIM>
  355. IGL_INLINE typename DerivedV::Scalar igl::AABB<DerivedV,DIM>::rotate(const bool dry_run)
  356. {
  357. if(is_root()) { return false; }
  358. // Biased order.
  359. //
  360. // Would be good to check for a ton of insertions whether only one of these
  361. // ever returns true.
  362. //
  363. // grandparent
  364. // ╱ ╲
  365. // parent pibling°
  366. // ╱ ╲ ╱ ╲
  367. // sibling this cuz1° cuz2°
  368. // ╱ ╲
  369. // nib1° nib2°
  370. // There is a _ton_ of repeated computation of surface areas and new-boxes in
  371. // these.
  372. // Rotate across first is much better. Then up seems slightly better than
  373. // down, but this is moot if we're chooseing the best one.
  374. const Scalar across_delta_sa = rotate_across(true);
  375. const Scalar up_delta_sa = rotate_up( true);
  376. const Scalar down_delta_sa = rotate_down( true);
  377. if(dry_run){ std::min({across_delta_sa,up_delta_sa,down_delta_sa}); }
  378. // conduct the rotate with smallest delta
  379. if(across_delta_sa <= up_delta_sa && across_delta_sa <= down_delta_sa)
  380. {
  381. return rotate_across(false);
  382. }else if(up_delta_sa <= down_delta_sa)
  383. {
  384. return rotate_up(false);
  385. }else
  386. {
  387. return rotate_down(false);
  388. }
  389. }
  390. template <typename DerivedV, int DIM>
  391. IGL_INLINE typename DerivedV::Scalar igl::AABB<DerivedV,DIM>::rotate_across(const bool dry_run)
  392. {
  393. // Before
  394. // grandparent
  395. // ╱ ╲
  396. // parent pibling
  397. // ╱ ╲ ╱ ╲
  398. // sibling this cuz1 cuz2
  399. //
  400. //
  401. // Candidates
  402. // grandparent
  403. // ╱ ╲
  404. // parent pibling
  405. // ╱ ╲ ╱ ╲
  406. // sibling cuz1 this cuz2
  407. //
  408. // Or
  409. // grandparent
  410. // ╱ ╲
  411. // parent pibling
  412. // ╱ ╲ ╱ ╲
  413. // sibling cuz2 cuz1 this
  414. auto * parent = this->m_parent;
  415. if(!parent) { return false; }
  416. const auto * grandparent = parent->m_parent;
  417. if(!grandparent) { return false; }
  418. auto * pibling = grandparent->m_left == parent ? grandparent->m_right : grandparent->m_left;
  419. if(!pibling) { return false; }
  420. const auto * sibling = parent->m_left == this ? parent->m_right : parent->m_left;
  421. const Scalar current_sa = box_surface_area(parent->m_box) + box_surface_area(pibling->m_box);
  422. const auto rotate_across_with = [&](
  423. bool inner_dry_run,
  424. igl::AABB<DerivedV,DIM> * cuz,
  425. igl::AABB<DerivedV,DIM> * other_cuz
  426. )->Scalar
  427. {
  428. // Before
  429. // grandparent
  430. // ╱ ╲
  431. // parent pibling
  432. // ╱ ╲ ╱ ╲
  433. // sibling this cuz other_cuz
  434. //
  435. //
  436. // Candidates
  437. // grandparent
  438. // ╱ ╲
  439. // parent pibling
  440. // ╱ ╲ ╱ ╲
  441. // sibling cuz this other_cuz
  442. if(!cuz){ return 0.0; }
  443. Eigen::AlignedBox<Scalar,DIM> new_parent_box;
  444. if(sibling) { new_parent_box.extend(sibling->m_box); }
  445. new_parent_box.extend(cuz->m_box);
  446. Eigen::AlignedBox<Scalar,DIM> new_pibling_box = this->m_box;
  447. if(other_cuz) { new_pibling_box.extend(other_cuz->m_box); }
  448. const Scalar new_sa =
  449. box_surface_area(new_parent_box) + box_surface_area(new_pibling_box);
  450. if(current_sa <= new_sa)
  451. {
  452. return 0.0;
  453. }
  454. if(!inner_dry_run)
  455. {
  456. assert(!dry_run);
  457. parent->m_box = new_parent_box;
  458. (parent->m_left == this ? parent->m_left : parent->m_right) = cuz;
  459. cuz->m_parent = parent;
  460. pibling->m_box = new_pibling_box;
  461. (pibling->m_left == cuz ? pibling->m_left : pibling->m_right) = this;
  462. this->m_parent = pibling;
  463. }
  464. return new_sa - current_sa;
  465. };
  466. auto * cuz1 = pibling->m_left;
  467. auto * cuz2 = pibling->m_right;
  468. const Scalar delta_1 = rotate_across_with(true,cuz1,cuz2);
  469. const Scalar delta_2 = rotate_across_with(true,cuz2,cuz1);
  470. if(delta_1 < delta_2)
  471. {
  472. return dry_run ? delta_1 : rotate_across_with(false,cuz1,cuz2);
  473. }else
  474. {
  475. return dry_run ? delta_2 : rotate_across_with(false,cuz2,cuz1);
  476. }
  477. }
  478. template <typename DerivedV, int DIM>
  479. IGL_INLINE typename DerivedV::Scalar igl::AABB<DerivedV,DIM>::rotate_up(const bool dry_run)
  480. {
  481. // Before
  482. // grandparent
  483. // ╱ ╲
  484. // other parent
  485. // ╱ ╲
  486. // this sibling
  487. //
  488. //
  489. // Candidate
  490. // grandparent
  491. // ╱ ╲
  492. // this parent
  493. // ╱ ╲
  494. // other sibling
  495. //
  496. auto * challenger = this;
  497. auto * parent = challenger->m_parent;
  498. if(!parent) { return false; }
  499. auto * grandparent = parent->m_parent;
  500. if(!grandparent) { return false; }
  501. auto * reining = grandparent->m_left == parent ? grandparent->m_right : grandparent->m_left;
  502. if(!reining) { return false; }
  503. auto * sibling = parent->m_left == challenger ? parent->m_right : parent->m_left;
  504. return rotate_up(dry_run,reining,grandparent,parent,challenger,sibling);
  505. }
  506. template <typename DerivedV, int DIM>
  507. IGL_INLINE typename DerivedV::Scalar igl::AABB<DerivedV,DIM>::rotate_down(const bool dry_run)
  508. {
  509. // Before
  510. // parent
  511. // ╱ ╲
  512. // this sibling
  513. // ╱ ╲
  514. // left right
  515. //
  516. //
  517. // Candidates
  518. // parent
  519. // ╱ ╲
  520. // left sibling
  521. // ╱ ╲
  522. // this right
  523. //
  524. // Or
  525. //
  526. // parent
  527. // ╱ ╲
  528. // right sibling
  529. // ╱ ╲
  530. // left this
  531. auto * parent = this->m_parent;
  532. if(!parent) { return false; }
  533. auto * sibling = parent->m_left == this ? parent->m_right : parent->m_left;
  534. if(!sibling) { return false; }
  535. const Scalar left_sa = rotate_up(true,this,parent,sibling,sibling->m_left,sibling->m_right);
  536. const Scalar right_sa = rotate_up(true,this,parent,sibling,sibling->m_right,sibling->m_left);
  537. if(left_sa < right_sa)
  538. {
  539. return dry_run ? left_sa : rotate_up(false,this,parent,sibling,sibling->m_left,sibling->m_right);
  540. }else
  541. {
  542. return dry_run ? right_sa : rotate_up(false,this,parent,sibling,sibling->m_right,sibling->m_left);
  543. }
  544. }
  545. template <typename DerivedV, int DIM>
  546. IGL_INLINE typename DerivedV::Scalar igl::AABB<DerivedV,DIM>::rotate_up(
  547. const bool dry_run,
  548. igl::AABB<DerivedV,DIM>* reining,
  549. igl::AABB<DerivedV,DIM>* grandparent,
  550. igl::AABB<DerivedV,DIM>* parent,
  551. igl::AABB<DerivedV,DIM>* challenger,
  552. igl::AABB<DerivedV,DIM>* sibling)
  553. {
  554. // if any are null return false
  555. if(!reining) { return false; }
  556. if(!grandparent) { return false; }
  557. if(!parent) { return false; }
  558. if(!challenger) { return false; }
  559. if(!sibling) { return false; }
  560. // Before
  561. // grandparent
  562. // ╱ ╲
  563. // reining parent
  564. // ╱ ╲
  565. // challenger sibling
  566. //
  567. //
  568. // Candidate
  569. // grandparent
  570. // ╱ ╲
  571. // challenger parent
  572. // ╱ ╲
  573. // reining sibling
  574. //
  575. auto sibling_sa = 0;
  576. // Sibling doesn't actually need to exist but probably should if parent is a
  577. // true internal node.
  578. if(sibling)
  579. {
  580. sibling_sa = box_surface_area(sibling->m_box);
  581. }
  582. const auto challenger_sa = box_surface_area(challenger->m_box);
  583. const auto parent_sa = box_surface_area(challenger->m_parent->m_box);
  584. const auto reining_sa = box_surface_area(reining->m_box);
  585. auto new_parent_box = reining->m_box;
  586. new_parent_box.extend(sibling->m_box);
  587. const auto new_parent_sa = box_surface_area(new_parent_box);
  588. // Cancels in comparison
  589. const auto before_sa = parent_sa ;// + reining_sa + challenger_sa + sibling_sa;
  590. const auto after_sa = new_parent_sa;// + reining_sa + challenger_sa + sibling_sa;
  591. if(before_sa <= after_sa)
  592. {
  593. // No improvment.
  594. return 0.0;
  595. }
  596. if(!dry_run)
  597. {
  598. // May reorder left and right but challenger doesn't matter.
  599. grandparent->m_left = challenger;
  600. grandparent->m_right = parent;
  601. challenger->m_parent = grandparent;
  602. parent->m_parent = grandparent;
  603. parent->m_left = reining;
  604. parent->m_right = sibling;
  605. reining->m_parent = parent;
  606. if(sibling){ sibling->m_parent = parent; }
  607. parent->m_box = new_parent_box;
  608. }
  609. return after_sa - before_sa;
  610. }
  611. template <typename DerivedV, int DIM>
  612. IGL_INLINE int igl::AABB<DerivedV,DIM>::subtree_size() const
  613. {
  614. // 1 for self
  615. int n = 1;
  616. int n_left = 0,n_right = 0;
  617. if(m_left != nullptr)
  618. {
  619. n_left = m_left->subtree_size();
  620. }
  621. if(m_right != nullptr)
  622. {
  623. n_right = m_right->subtree_size();
  624. }
  625. n += 2*std::max(n_left,n_right);
  626. return n;
  627. }
  628. template <typename DerivedV, int DIM>
  629. IGL_INLINE void igl::AABB<DerivedV,DIM>::rotate_lineage()
  630. {
  631. std::vector<igl::AABB<DerivedV, DIM> *> lineage;
  632. {
  633. auto * node = this;
  634. while(node)
  635. {
  636. lineage.push_back(node);
  637. node = node->m_parent;
  638. }
  639. }
  640. // O(h)
  641. while(!lineage.empty())
  642. {
  643. auto * node = lineage.back();
  644. lineage.pop_back();
  645. assert(node);
  646. const bool ret = node->rotate();
  647. }
  648. }
  649. template <typename DerivedV, int DIM>
  650. IGL_INLINE bool igl::AABB<DerivedV,DIM>::append_intersecting_leaves(
  651. const Eigen::AlignedBox<igl::AABB<DerivedV,DIM>::Scalar,DIM> & box,
  652. std::vector<const igl::AABB<DerivedV,DIM>*> & leaves) const
  653. {
  654. if(!box.intersects(m_box)){ return false;}
  655. if(is_leaf())
  656. {
  657. leaves.push_back(this);
  658. return true;
  659. }
  660. bool any_left = (m_left ? m_left->append_intersecting_leaves(box,leaves) : false);
  661. bool any_right = (m_right ? m_right->append_intersecting_leaves(box,leaves) : false);
  662. return any_left || any_right;
  663. }
  664. template <typename DerivedV, int DIM>
  665. IGL_INLINE typename DerivedV::Scalar igl::AABB<DerivedV,DIM>::internal_surface_area() const
  666. {
  667. // Don't include self (parent's call will add me if I'm not a root or leaf)
  668. Scalar surface_area = 0;
  669. if(m_left && !m_left->is_leaf())
  670. {
  671. surface_area += box_surface_area(m_left->m_box);
  672. surface_area += m_left->internal_surface_area();
  673. }
  674. if(m_right && !m_right->is_leaf())
  675. {
  676. surface_area += box_surface_area(m_right->m_box);
  677. surface_area += m_right->internal_surface_area();
  678. }
  679. return surface_area;
  680. }
  681. template <typename DerivedV, int DIM>
  682. IGL_INLINE void igl::AABB<DerivedV,DIM>::validate() const
  683. {
  684. if(this->is_leaf())
  685. {
  686. assert(this->m_primitive >= 0 || this->is_root());
  687. }
  688. if(this->m_left)
  689. {
  690. assert(this->m_box.contains(this->m_left->m_box));
  691. assert(this->m_left->m_parent == this);
  692. this->m_left->validate();
  693. }
  694. if(this->m_right)
  695. {
  696. assert(this->m_box.contains(this->m_right->m_box));
  697. assert(this->m_right->m_parent == this);
  698. this->m_right->validate();
  699. }
  700. }
  701. template <typename DerivedV, int DIM>
  702. IGL_INLINE void igl::AABB<DerivedV,DIM>::print(const int depth) const
  703. {
  704. const auto indent = std::string(depth*2,' ');
  705. printf("%s%p",indent.c_str(),this);
  706. if(this->is_leaf())
  707. {
  708. printf(" [%d]",this->m_primitive);
  709. }
  710. printf("\n");
  711. if(this->m_left)
  712. {
  713. assert(this->m_box.contains(this->m_left->m_box));
  714. assert(this->m_left->m_parent == this);
  715. this->m_left->print(depth+1);
  716. }
  717. if(this->m_right)
  718. {
  719. assert(this->m_box.contains(this->m_right->m_box));
  720. assert(this->m_right->m_parent == this);
  721. this->m_right->print(depth+1);
  722. }
  723. }
  724. template <typename DerivedV, int DIM>
  725. IGL_INLINE int igl::AABB<DerivedV,DIM>::size() const
  726. {
  727. return 1 +
  728. (this->m_left ? this->m_left ->size():0) +
  729. (this->m_right? this->m_right->size():0);
  730. }
  731. template <typename DerivedV, int DIM>
  732. IGL_INLINE int igl::AABB<DerivedV,DIM>::height() const
  733. {
  734. return 1 + std::max(
  735. (this->m_left ?this->m_left ->height():0),
  736. (this->m_right?this->m_right->height():0));
  737. }
  738. template <typename DerivedV, int DIM>
  739. IGL_INLINE void igl::AABB<DerivedV,DIM>::set_min(
  740. const RowVectorDIMS & /* p */,
  741. const Scalar sqr_d_candidate,
  742. const int & i_candidate,
  743. const RowVectorDIMS & c_candidate,
  744. Scalar & sqr_d,
  745. int & i,
  746. Eigen::PlainObjectBase<RowVectorDIMS> & c) const
  747. {
  748. if(sqr_d_candidate < sqr_d)
  749. {
  750. i = i_candidate;
  751. c = c_candidate;
  752. sqr_d = sqr_d_candidate;
  753. }
  754. }
  755. ///////////////////////////////////////////////////////////////////////////////
  756. // Templated member functions
  757. ///////////////////////////////////////////////////////////////////////////////
  758. template <typename DerivedV, int DIM>
  759. template <typename DerivedEle, typename Derivedbb_mins, typename Derivedbb_maxs, typename Derivedelements>
  760. IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
  761. const Eigen::MatrixBase<DerivedV> & V,
  762. const Eigen::MatrixBase<DerivedEle> & Ele,
  763. const Eigen::MatrixBase<Derivedbb_mins> & bb_mins,
  764. const Eigen::MatrixBase<Derivedbb_maxs> & bb_maxs,
  765. const Eigen::MatrixBase<Derivedelements> & elements,
  766. const int i)
  767. {
  768. clear();
  769. if(bb_mins.size() > 0)
  770. {
  771. assert(bb_mins.rows() == bb_maxs.rows() && "Serial tree arrays must match");
  772. assert(bb_mins.cols() == V.cols() && "Serial tree array dim must match V");
  773. assert(bb_mins.cols() == bb_maxs.cols() && "Serial tree arrays must match");
  774. assert(bb_mins.rows() == elements.rows() &&
  775. "Serial tree arrays must match");
  776. // construct from serialization
  777. m_box.extend(bb_mins.row(i).transpose());
  778. m_box.extend(bb_maxs.row(i).transpose());
  779. m_primitive = elements(i);
  780. // Not leaf then recurse
  781. if(m_primitive == -1)
  782. {
  783. m_left = new AABB();
  784. m_left->init( V,Ele,bb_mins,bb_maxs,elements,2*i+1);
  785. m_left->m_parent = this;
  786. m_right = new AABB();
  787. m_right->init( V,Ele,bb_mins,bb_maxs,elements,2*i+2);
  788. m_right->m_parent = this;
  789. //m_depth = std::max( m_left->m_depth, m_right->m_depth)+1;
  790. }
  791. }else
  792. {
  793. Eigen::VectorXi allI = colon<int>(0,Ele.rows()-1);
  794. MatrixXDIMS BC;
  795. if(Ele.cols() == 1)
  796. {
  797. // points
  798. BC = V;
  799. }else
  800. {
  801. // Simplices
  802. barycenter(V,Ele,BC);
  803. }
  804. Eigen::MatrixXi SI(BC.rows(),BC.cols());
  805. {
  806. MatrixXDIMS _;
  807. Eigen::MatrixXi IS;
  808. igl::sort(BC,1,true,_,IS);
  809. // Need SI(i) to tell which place i would be sorted into
  810. const int dim = IS.cols();
  811. for(int i = 0;i<IS.rows();i++)
  812. {
  813. for(int d = 0;d<dim;d++)
  814. {
  815. SI(IS(i,d),d) = i;
  816. }
  817. }
  818. }
  819. init(V,Ele,SI,allI);
  820. }
  821. }
  822. template <typename DerivedV, int DIM>
  823. template <typename DerivedEle>
  824. void igl::AABB<DerivedV,DIM>::init(
  825. const Eigen::MatrixBase<DerivedV> & V,
  826. const Eigen::MatrixBase<DerivedEle> & Ele)
  827. {
  828. // clear will be immediately called...
  829. return init(V,Ele,MatrixXDIMS(),MatrixXDIMS(),Eigen::VectorXi(),0);
  830. }
  831. template <typename DerivedV, int DIM>
  832. template <
  833. typename DerivedEle,
  834. typename DerivedSI,
  835. typename DerivedI>
  836. IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
  837. const Eigen::MatrixBase<DerivedV> & V,
  838. const Eigen::MatrixBase<DerivedEle> & Ele,
  839. const Eigen::MatrixBase<DerivedSI> & SI,
  840. const Eigen::MatrixBase<DerivedI> & I)
  841. {
  842. clear();
  843. if(V.size() == 0 || Ele.size() == 0 || I.size() == 0)
  844. {
  845. return;
  846. }
  847. assert(DIM == V.cols() && "V.cols() should matched declared dimension");
  848. //const Scalar inf = numeric_limits<Scalar>::infinity();
  849. m_box = Eigen::AlignedBox<Scalar,DIM>();
  850. // Compute bounding box
  851. for(int i = 0;i<I.rows();i++)
  852. {
  853. for(int c = 0;c<Ele.cols();c++)
  854. {
  855. m_box.extend(V.row(Ele(I(i),c)).transpose());
  856. m_box.extend(V.row(Ele(I(i),c)).transpose());
  857. }
  858. }
  859. switch(I.size())
  860. {
  861. case 0:
  862. {
  863. assert(false);
  864. }
  865. case 1:
  866. {
  867. m_primitive = I(0);
  868. break;
  869. }
  870. default:
  871. {
  872. // Compute longest direction
  873. int max_d = -1;
  874. m_box.diagonal().maxCoeff(&max_d);
  875. // Can't use median on BC directly because many may have same value,
  876. // but can use median on sorted BC indices
  877. Eigen::VectorXi SIdI(I.rows());
  878. for(int i = 0;i<I.rows();i++)
  879. {
  880. SIdI(i) = SI(I(i),max_d);
  881. }
  882. // Pass by copy to avoid changing input
  883. const auto median = [](Eigen::VectorXi A)->int
  884. {
  885. size_t n = (A.size()-1)/2;
  886. std::nth_element(A.data(),A.data()+n,A.data()+A.size());
  887. return A(n);
  888. };
  889. const int med = median(SIdI);
  890. Eigen::VectorXi LI((I.rows()+1)/2),RI(I.rows()/2);
  891. assert(LI.rows()+RI.rows() == I.rows());
  892. // Distribute left and right
  893. {
  894. int li = 0;
  895. int ri = 0;
  896. for(int i = 0;i<I.rows();i++)
  897. {
  898. if(SIdI(i)<=med)
  899. {
  900. LI(li++) = I(i);
  901. }else
  902. {
  903. RI(ri++) = I(i);
  904. }
  905. }
  906. }
  907. //m_depth = 0;
  908. if(LI.rows()>0)
  909. {
  910. m_left = new AABB();
  911. m_left->init(V,Ele,SI,LI);
  912. m_left->m_parent = this;
  913. //m_depth = std::max(m_depth, m_left->m_depth+1);
  914. }
  915. if(RI.rows()>0)
  916. {
  917. m_right = new AABB();
  918. m_right->init(V,Ele,SI,RI);
  919. m_right->m_parent = this;
  920. //m_depth = std::max(m_depth, m_right->m_depth+1);
  921. }
  922. }
  923. }
  924. }
  925. template <typename DerivedV, int DIM>
  926. template <typename DerivedEle>
  927. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::update_primitive(
  928. const Eigen::MatrixBase<DerivedV> & V,
  929. const Eigen::MatrixBase<DerivedEle> & Ele,
  930. const Scalar pad)
  931. {
  932. assert(this->is_leaf());
  933. assert(this->m_primitive >= 0 && this->m_primitive < Ele.rows());
  934. Eigen::AlignedBox<double, 3> new_box;
  935. for(int c = 0;c<Ele.cols();c++)
  936. {
  937. new_box.extend(V.row(Ele(this->m_primitive,c)).transpose());
  938. }
  939. return this->update(new_box,pad);
  940. }
  941. template <typename DerivedV, int DIM>
  942. IGL_INLINE igl::AABB<DerivedV,DIM>* igl::AABB<DerivedV,DIM>::insert(AABB * other)
  943. {
  944. // test if this is the same pointer as other
  945. if(this == other)
  946. {
  947. // Only expecting this to happen when this/other are a singleton tree
  948. assert(this->is_root() && this->is_leaf());
  949. // Nothing changed.
  950. return this;
  951. }
  952. if(this->is_leaf())
  953. {
  954. return this->insert_as_sibling(other);
  955. }
  956. // internal node case
  957. if(!this->m_box.contains(other->m_box))
  958. {
  959. // it's annoying to have these special root handling cases. I wonder if the
  960. // root should have been an ∞ node...
  961. return insert_as_sibling(other);
  962. }
  963. Eigen::AlignedBox<Scalar,DIM> left_grow = this->m_left->m_box;
  964. left_grow.extend(other->m_box);
  965. Eigen::AlignedBox<Scalar,DIM> right_grow = this->m_right->m_box;
  966. right_grow.extend(other->m_box);
  967. const auto left_surface_area_increase =
  968. box_surface_area(left_grow) - box_surface_area(this->m_left->m_box);
  969. const auto right_surface_area_increase =
  970. box_surface_area(right_grow) - box_surface_area(this->m_right->m_box);
  971. assert(left_surface_area_increase >= 0);
  972. assert(right_surface_area_increase >= 0);
  973. // Handle both (left_surface_area_increase <= 0 && right_surface_area_increase <= 0)
  974. return left_surface_area_increase < right_surface_area_increase ?
  975. this->m_left->insert(other) :
  976. this->m_right->insert(other);
  977. }
  978. template <typename DerivedV, int DIM>
  979. template <typename DerivedEle, typename Derivedq>
  980. IGL_INLINE std::vector<int> igl::AABB<DerivedV,DIM>::find(
  981. const Eigen::MatrixBase<DerivedV> & V,
  982. const Eigen::MatrixBase<DerivedEle> & Ele,
  983. const Eigen::MatrixBase<Derivedq> & q,
  984. const bool first) const
  985. {
  986. assert(q.size() == DIM &&
  987. "Query dimension should match aabb dimension");
  988. assert(Ele.cols() == V.cols()+1 &&
  989. "AABB::find only makes sense for (d+1)-simplices");
  990. // Check if outside bounding box
  991. bool inside = m_box.contains(q.transpose());
  992. if(!inside)
  993. {
  994. return std::vector<int>();
  995. }
  996. assert(m_primitive==-1 || (m_left == nullptr && m_right == nullptr));
  997. if(is_leaf())
  998. {
  999. if(AABB_all_positive_barycentric_coordinates_helper<
  1000. DerivedV,DerivedEle,Derivedq, DIM>::compute(V,Ele,m_primitive,q))
  1001. {
  1002. return std::vector<int>(1,m_primitive);
  1003. }else
  1004. {
  1005. return std::vector<int>();
  1006. }
  1007. }
  1008. std::vector<int> left = m_left->find(V,Ele,q,first);
  1009. if(first && !left.empty())
  1010. {
  1011. return left;
  1012. }
  1013. std::vector<int> right = m_right->find(V,Ele,q,first);
  1014. if(first)
  1015. {
  1016. return right;
  1017. }
  1018. left.insert(left.end(),right.begin(),right.end());
  1019. return left;
  1020. }
  1021. template <typename DerivedV, int DIM>
  1022. template <typename Derivedbb_mins, typename Derivedbb_maxs, typename Derivedelements>
  1023. IGL_INLINE void igl::AABB<DerivedV,DIM>::serialize(
  1024. Eigen::PlainObjectBase<Derivedbb_mins> & bb_mins,
  1025. Eigen::PlainObjectBase<Derivedbb_maxs> & bb_maxs,
  1026. Eigen::PlainObjectBase<Derivedelements> & elements,
  1027. const int i) const
  1028. {
  1029. // Calling for root then resize output
  1030. if(i==0)
  1031. {
  1032. const int m = subtree_size();
  1033. //cout<<"m: "<<m<<endl;
  1034. bb_mins.resize(m,DIM);
  1035. bb_maxs.resize(m,DIM);
  1036. elements.resize(m,1);
  1037. }
  1038. //cout<<i<<" ";
  1039. bb_mins.row(i) = m_box.min();
  1040. bb_maxs.row(i) = m_box.max();
  1041. elements(i) = m_primitive;
  1042. if(m_left != nullptr)
  1043. {
  1044. m_left->serialize(bb_mins,bb_maxs,elements,2*i+1);
  1045. }
  1046. if(m_right != nullptr)
  1047. {
  1048. m_right->serialize(bb_mins,bb_maxs,elements,2*i+2);
  1049. }
  1050. }
  1051. template <typename DerivedV, int DIM>
  1052. template <typename DerivedEle>
  1053. IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
  1054. igl::AABB<DerivedV,DIM>::squared_distance(
  1055. const Eigen::MatrixBase<DerivedV> & V,
  1056. const Eigen::MatrixBase<DerivedEle> & Ele,
  1057. const RowVectorDIMS & p,
  1058. int & i,
  1059. Eigen::PlainObjectBase<RowVectorDIMS> & c) const
  1060. {
  1061. return squared_distance(V,Ele,p,std::numeric_limits<Scalar>::infinity(),i,c);
  1062. }
  1063. template <typename DerivedV, int DIM>
  1064. template <typename DerivedEle>
  1065. IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
  1066. igl::AABB<DerivedV,DIM>::squared_distance(
  1067. const Eigen::MatrixBase<DerivedV> & V,
  1068. const Eigen::MatrixBase<DerivedEle> & Ele,
  1069. const RowVectorDIMS & p,
  1070. Scalar low_sqr_d,
  1071. Scalar up_sqr_d,
  1072. int & i,
  1073. Eigen::PlainObjectBase<RowVectorDIMS> & c) const
  1074. {
  1075. //assert(low_sqr_d <= up_sqr_d);
  1076. if(low_sqr_d > up_sqr_d)
  1077. {
  1078. return low_sqr_d;
  1079. }
  1080. Scalar sqr_d = up_sqr_d;
  1081. //assert(DIM == 3 && "Code has only been tested for DIM == 3");
  1082. assert((Ele.cols() == 3 || Ele.cols() == 2 || Ele.cols() == 1)
  1083. && "Code has only been tested for simplex sizes 3,2,1");
  1084. assert(m_primitive==-1 || (m_left == nullptr && m_right == nullptr));
  1085. if(is_leaf())
  1086. {
  1087. leaf_squared_distance(V,Ele,p,low_sqr_d,sqr_d,i,c);
  1088. }else
  1089. {
  1090. bool looked_left = false;
  1091. bool looked_right = false;
  1092. const auto & look_left = [&]()
  1093. {
  1094. int i_left;
  1095. RowVectorDIMS c_left = c;
  1096. Scalar sqr_d_left =
  1097. m_left->squared_distance(V,Ele,p,low_sqr_d,sqr_d,i_left,c_left);
  1098. this->set_min(p,sqr_d_left,i_left,c_left,sqr_d,i,c);
  1099. looked_left = true;
  1100. };
  1101. const auto & look_right = [&]()
  1102. {
  1103. int i_right;
  1104. RowVectorDIMS c_right = c;
  1105. Scalar sqr_d_right =
  1106. m_right->squared_distance(V,Ele,p,low_sqr_d,sqr_d,i_right,c_right);
  1107. this->set_min(p,sqr_d_right,i_right,c_right,sqr_d,i,c);
  1108. looked_right = true;
  1109. };
  1110. // must look left or right if in box
  1111. if(m_left->m_box.contains(p.transpose()))
  1112. {
  1113. look_left();
  1114. }
  1115. if(m_right->m_box.contains(p.transpose()))
  1116. {
  1117. look_right();
  1118. }
  1119. // if haven't looked left and could be less than current min, then look
  1120. Scalar left_up_sqr_d =
  1121. m_left->m_box.squaredExteriorDistance(p.transpose());
  1122. Scalar right_up_sqr_d =
  1123. m_right->m_box.squaredExteriorDistance(p.transpose());
  1124. if(left_up_sqr_d < right_up_sqr_d)
  1125. {
  1126. if(!looked_left && left_up_sqr_d<sqr_d)
  1127. {
  1128. look_left();
  1129. }
  1130. if( !looked_right && right_up_sqr_d<sqr_d)
  1131. {
  1132. look_right();
  1133. }
  1134. }else
  1135. {
  1136. if( !looked_right && right_up_sqr_d<sqr_d)
  1137. {
  1138. look_right();
  1139. }
  1140. if(!looked_left && left_up_sqr_d<sqr_d)
  1141. {
  1142. look_left();
  1143. }
  1144. }
  1145. }
  1146. return sqr_d;
  1147. }
  1148. template <typename DerivedV, int DIM>
  1149. template <typename DerivedEle>
  1150. IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
  1151. igl::AABB<DerivedV,DIM>::squared_distance(
  1152. const Eigen::MatrixBase<DerivedV> & V,
  1153. const Eigen::MatrixBase<DerivedEle> & Ele,
  1154. const RowVectorDIMS & p,
  1155. Scalar up_sqr_d,
  1156. int & i,
  1157. Eigen::PlainObjectBase<RowVectorDIMS> & c) const
  1158. {
  1159. return squared_distance(V,Ele,p,0.0,up_sqr_d,i,c);
  1160. }
  1161. template <typename DerivedV, int DIM>
  1162. template <
  1163. typename DerivedEle,
  1164. typename DerivedP,
  1165. typename DerivedsqrD,
  1166. typename DerivedI,
  1167. typename DerivedC>
  1168. IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
  1169. const Eigen::MatrixBase<DerivedV> & V,
  1170. const Eigen::MatrixBase<DerivedEle> & Ele,
  1171. const Eigen::MatrixBase<DerivedP> & P,
  1172. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  1173. Eigen::PlainObjectBase<DerivedI> & I,
  1174. Eigen::PlainObjectBase<DerivedC> & C) const
  1175. {
  1176. assert(P.cols() == V.cols() && "cols in P should match dim of cols in V");
  1177. sqrD.resize(P.rows(),1);
  1178. I.resize(P.rows(),1);
  1179. C.resizeLike(P);
  1180. // O( #P * log #Ele ), where log #Ele is really the depth of this AABB
  1181. // hierarchy
  1182. //for(int p = 0;p<P.rows();p++)
  1183. igl::parallel_for(P.rows(),[&](int p)
  1184. {
  1185. RowVectorDIMS Pp = P.row(p).template head<DIM>(), c;
  1186. int Ip;
  1187. sqrD(p) = squared_distance(V,Ele,Pp,Ip,c);
  1188. I(p) = Ip;
  1189. C.row(p).head(DIM) = c;
  1190. },
  1191. 10000);
  1192. }
  1193. template <typename DerivedV, int DIM>
  1194. template <
  1195. typename DerivedEle,
  1196. typename Derivedother_V,
  1197. typename Derivedother_Ele,
  1198. typename DerivedsqrD,
  1199. typename DerivedI,
  1200. typename DerivedC>
  1201. IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
  1202. const Eigen::MatrixBase<DerivedV> & V,
  1203. const Eigen::MatrixBase<DerivedEle> & Ele,
  1204. const AABB<Derivedother_V,DIM> & other,
  1205. const Eigen::MatrixBase<Derivedother_V> & other_V,
  1206. const Eigen::MatrixBase<Derivedother_Ele> & other_Ele,
  1207. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  1208. Eigen::PlainObjectBase<DerivedI> & I,
  1209. Eigen::PlainObjectBase<DerivedC> & C) const
  1210. {
  1211. assert(other_Ele.cols() == 1 &&
  1212. "Only implemented for other as list of points");
  1213. assert(other_V.cols() == V.cols() && "other must match this dimension");
  1214. sqrD.setConstant(other_Ele.rows(),1,std::numeric_limits<double>::infinity());
  1215. I.resize(other_Ele.rows(),1);
  1216. C.resize(other_Ele.rows(),other_V.cols());
  1217. // All points in other_V currently think they need to check against root of
  1218. // this. The point of using another AABB is to quickly prune chunks of
  1219. // other_V so that most points just check some subtree of this.
  1220. // This holds a conservative estimate of max(sqr_D) where sqr_D is the
  1221. // current best minimum squared distance for all points in this subtree
  1222. double up_sqr_d = std::numeric_limits<double>::infinity();
  1223. squared_distance_helper(
  1224. V,Ele,&other,other_V,other_Ele,0,up_sqr_d,sqrD,I,C);
  1225. }
  1226. template <typename DerivedV, int DIM>
  1227. template <
  1228. typename DerivedEle,
  1229. typename Derivedother_V,
  1230. typename Derivedother_Ele,
  1231. typename DerivedsqrD,
  1232. typename DerivedI,
  1233. typename DerivedC>
  1234. IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
  1235. igl::AABB<DerivedV,DIM>::squared_distance_helper(
  1236. const Eigen::MatrixBase<DerivedV> & V,
  1237. const Eigen::MatrixBase<DerivedEle> & Ele,
  1238. const AABB<Derivedother_V,DIM> * other,
  1239. const Eigen::MatrixBase<Derivedother_V> & other_V,
  1240. const Eigen::MatrixBase<Derivedother_Ele> & other_Ele,
  1241. const Scalar /*up_sqr_d*/,
  1242. Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
  1243. Eigen::PlainObjectBase<DerivedI> & I,
  1244. Eigen::PlainObjectBase<DerivedC> & C) const
  1245. {
  1246. // This implementation is a bit disappointing. There's no major speed up. Any
  1247. // performance gains seem to come from accidental cache coherency and
  1248. // diminish for larger "other" (the opposite of what was intended).
  1249. // Base case
  1250. if(other->is_leaf() && this->is_leaf())
  1251. {
  1252. Scalar sqr_d = sqrD(other->m_primitive);
  1253. int i = I(other->m_primitive);
  1254. RowVectorDIMS c = C.row( other->m_primitive);
  1255. RowVectorDIMS p = other_V.row(other->m_primitive);
  1256. leaf_squared_distance(V,Ele,p,sqr_d,i,c);
  1257. sqrD( other->m_primitive) = sqr_d;
  1258. I( other->m_primitive) = i;
  1259. C.row(other->m_primitive) = c;
  1260. //cout<<"leaf: "<<sqr_d<<endl;
  1261. //other->m_low_sqr_d = sqr_d;
  1262. return sqr_d;
  1263. }
  1264. if(other->is_leaf())
  1265. {
  1266. Scalar sqr_d = sqrD(other->m_primitive);
  1267. int i = I(other->m_primitive);
  1268. RowVectorDIMS c = C.row( other->m_primitive);
  1269. RowVectorDIMS p = other_V.row(other->m_primitive);
  1270. sqr_d = squared_distance(V,Ele,p,sqr_d,i,c);
  1271. sqrD( other->m_primitive) = sqr_d;
  1272. I( other->m_primitive) = i;
  1273. C.row(other->m_primitive) = c;
  1274. //other->m_low_sqr_d = sqr_d;
  1275. return sqr_d;
  1276. }
  1277. //// Exact minimum squared distance between arbitrary primitives inside this and
  1278. //// othre's bounding boxes
  1279. //const auto & min_squared_distance = [&](
  1280. // const AABB<DerivedV,DIM> * A,
  1281. // const AABB<Derivedother_V,DIM> * B)->Scalar
  1282. //{
  1283. // return A->m_box.squaredExteriorDistance(B->m_box);
  1284. //};
  1285. if(this->is_leaf())
  1286. {
  1287. //if(min_squared_distance(this,other) < other->m_low_sqr_d)
  1288. if(true)
  1289. {
  1290. this->squared_distance_helper(
  1291. V,Ele,other->m_left,other_V,other_Ele,0,sqrD,I,C);
  1292. this->squared_distance_helper(
  1293. V,Ele,other->m_right,other_V,other_Ele,0,sqrD,I,C);
  1294. }else
  1295. {
  1296. // This is never reached...
  1297. }
  1298. //// we know other is not a leaf
  1299. //other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
  1300. return 0;
  1301. }
  1302. // FORCE DOWN TO OTHER LEAF EVAL
  1303. //if(min_squared_distance(this,other) < other->m_low_sqr_d)
  1304. if(true)
  1305. {
  1306. if(true)
  1307. {
  1308. this->squared_distance_helper(
  1309. V,Ele,other->m_left,other_V,other_Ele,0,sqrD,I,C);
  1310. this->squared_distance_helper(
  1311. V,Ele,other->m_right,other_V,other_Ele,0,sqrD,I,C);
  1312. }else // this direction never seems to be faster
  1313. {
  1314. this->m_left->squared_distance_helper(
  1315. V,Ele,other,other_V,other_Ele,0,sqrD,I,C);
  1316. this->m_right->squared_distance_helper(
  1317. V,Ele,other,other_V,other_Ele,0,sqrD,I,C);
  1318. }
  1319. }else
  1320. {
  1321. // this is never reached ... :-(
  1322. }
  1323. //// we know other is not a leaf
  1324. //other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
  1325. return 0;
  1326. }
  1327. template <typename DerivedV, int DIM>
  1328. template <typename DerivedEle>
  1329. IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
  1330. const Eigen::MatrixBase<DerivedV> & V,
  1331. const Eigen::MatrixBase<DerivedEle> & Ele,
  1332. const RowVectorDIMS & p,
  1333. const Scalar low_sqr_d,
  1334. Scalar & sqr_d,
  1335. int & i,
  1336. Eigen::PlainObjectBase<RowVectorDIMS> & c) const
  1337. {
  1338. if(low_sqr_d > sqr_d)
  1339. {
  1340. sqr_d = low_sqr_d;
  1341. return;
  1342. }
  1343. RowVectorDIMS c_candidate;
  1344. Scalar sqr_d_candidate;
  1345. igl::point_simplex_squared_distance<DIM>(
  1346. p,V,Ele,m_primitive,sqr_d_candidate,c_candidate);
  1347. set_min(p,sqr_d_candidate,m_primitive,c_candidate,sqr_d,i,c);
  1348. }
  1349. template <typename DerivedV, int DIM>
  1350. template <typename DerivedEle>
  1351. IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
  1352. const Eigen::MatrixBase<DerivedV> & V,
  1353. const Eigen::MatrixBase<DerivedEle> & Ele,
  1354. const RowVectorDIMS & p,
  1355. Scalar & sqr_d,
  1356. int & i,
  1357. Eigen::PlainObjectBase<RowVectorDIMS> & c) const
  1358. {
  1359. return leaf_squared_distance(V,Ele,p,0,sqr_d,i,c);
  1360. }
  1361. template <typename DerivedV, int DIM>
  1362. template <typename DerivedEle>
  1363. IGL_INLINE bool
  1364. igl::AABB<DerivedV,DIM>::intersect_ray(
  1365. const Eigen::MatrixBase<DerivedV> & V,
  1366. const Eigen::MatrixBase<DerivedEle> & Ele,
  1367. const RowVectorDIMS & origin,
  1368. const RowVectorDIMS & dir,
  1369. std::vector<igl::Hit<typename DerivedV::Scalar>> & hits) const
  1370. {
  1371. RowVectorDIMS inv_dir = dir.cwiseInverse();
  1372. RowVectorDIMS inv_dir_pad = inv_dir;
  1373. igl::increment_ulp(inv_dir_pad, 2);
  1374. return intersect_ray_opt(V, Ele, origin, dir, inv_dir, inv_dir_pad, hits);
  1375. }
  1376. template <typename DerivedV, int DIM>
  1377. template <typename DerivedEle>
  1378. IGL_INLINE bool
  1379. igl::AABB<DerivedV,DIM>::intersect_ray(
  1380. const Eigen::MatrixBase<DerivedV> & V,
  1381. const Eigen::MatrixBase<DerivedEle> & Ele,
  1382. const RowVectorDIMS & origin,
  1383. const RowVectorDIMS & dir,
  1384. igl::Hit<typename DerivedV::Scalar> & hit) const
  1385. {
  1386. #if false
  1387. // BFS
  1388. std::queue<const AABB *> Q;
  1389. // Or DFS
  1390. //std::stack<const AABB *> Q;
  1391. Q.push(this);
  1392. bool any_hit = false;
  1393. hit.t = std::numeric_limits<Scalar>::infinity();
  1394. while(!Q.empty())
  1395. {
  1396. const AABB * tree = Q.front();
  1397. //const AABB * tree = Q.top();
  1398. Q.pop();
  1399. {
  1400. Scalar _1,_2;
  1401. if(!ray_box_intersect(
  1402. origin,dir,tree->m_box,Scalar(0),Scalar(hit.t),_1,_2))
  1403. {
  1404. continue;
  1405. }
  1406. }
  1407. if(tree->is_leaf())
  1408. {
  1409. // Actually process elements
  1410. assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
  1411. igl::Hit<typename DerivedV::Scalar> leaf_hit;
  1412. if(
  1413. ray_mesh_intersect(origin,dir,V,Ele.row(tree->m_primitive),leaf_hit)&&
  1414. leaf_hit.t < hit.t)
  1415. {
  1416. // correct the id
  1417. leaf_hit.id = tree->m_primitive;
  1418. hit = leaf_hit;
  1419. }
  1420. continue;
  1421. }
  1422. // Add children to queue
  1423. Q.push(tree->m_left);
  1424. Q.push(tree->m_right);
  1425. }
  1426. return any_hit;
  1427. #else
  1428. // DFS
  1429. return intersect_ray(
  1430. V,Ele,origin,dir,std::numeric_limits<Scalar>::infinity(),hit);
  1431. #endif
  1432. }
  1433. template <typename DerivedV, int DIM>
  1434. template <typename DerivedEle>
  1435. IGL_INLINE bool
  1436. igl::AABB<DerivedV,DIM>::intersect_ray(
  1437. const Eigen::MatrixBase<DerivedV> & V,
  1438. const Eigen::MatrixBase<DerivedEle> & Ele,
  1439. const RowVectorDIMS & origin,
  1440. const RowVectorDIMS & dir,
  1441. const Scalar _min_t,
  1442. igl::Hit<typename DerivedV::Scalar> & hit) const
  1443. {
  1444. RowVectorDIMS inv_dir = dir.cwiseInverse();
  1445. RowVectorDIMS inv_dir_pad = inv_dir;
  1446. igl::increment_ulp(inv_dir_pad, 2);
  1447. return intersect_ray_opt(V, Ele, origin, dir, inv_dir, inv_dir_pad, _min_t, hit);
  1448. }
  1449. template <typename DerivedV, int DIM>
  1450. template <
  1451. typename DerivedEle,
  1452. typename DerivedOrigin,
  1453. typename DerivedDir,
  1454. typename DerivedI,
  1455. typename DerivedT,
  1456. typename DerivedUV>
  1457. IGL_INLINE void igl::AABB<DerivedV,DIM>::intersect_ray(
  1458. const Eigen::MatrixBase<DerivedV> & V,
  1459. const Eigen::MatrixBase<DerivedEle> & Ele,
  1460. const Eigen::MatrixBase<DerivedOrigin> & origin,
  1461. const Eigen::MatrixBase<DerivedDir> & dir,
  1462. const Scalar min_t,
  1463. Eigen::PlainObjectBase<DerivedI> & I,
  1464. Eigen::PlainObjectBase<DerivedT> & T,
  1465. Eigen::PlainObjectBase<DerivedUV> & UV)
  1466. {
  1467. assert(origin.rows() == dir.rows());
  1468. I.setConstant(origin.rows(),1,-1);
  1469. T.setConstant(origin.rows(),1,std::numeric_limits<Scalar>::quiet_NaN());
  1470. UV.resize(origin.rows(),2);
  1471. igl::parallel_for(origin.rows(),[&](int i)
  1472. {
  1473. RowVectorDIMS origin_i = origin.row(i);
  1474. RowVectorDIMS dir_i = dir.row(i);
  1475. igl::Hit<typename DerivedV::Scalar> hit_i;
  1476. if(intersect_ray(V,Ele,origin_i,dir_i,min_t,hit_i))
  1477. {
  1478. I(i) = hit_i.id;
  1479. UV.row(i) << hit_i.u, hit_i.v;
  1480. T(i) = hit_i.t;
  1481. }
  1482. },
  1483. 10000);
  1484. }
  1485. template <typename DerivedV, int DIM>
  1486. template <
  1487. typename DerivedEle,
  1488. typename DerivedOrigin,
  1489. typename DerivedDir>
  1490. IGL_INLINE void igl::AABB<DerivedV,DIM>::intersect_ray(
  1491. const Eigen::MatrixBase<DerivedV> & V,
  1492. const Eigen::MatrixBase<DerivedEle> & Ele,
  1493. const Eigen::MatrixBase<DerivedOrigin> & origin,
  1494. const Eigen::MatrixBase<DerivedDir> & dir,
  1495. std::vector<std::vector<igl::Hit<typename DerivedV::Scalar>>> & hits)
  1496. {
  1497. assert(origin.rows() == dir.rows());
  1498. hits.resize(origin.rows());
  1499. igl::parallel_for(origin.rows(),[&](int i)
  1500. {
  1501. RowVectorDIMS origin_i = origin.row(i);
  1502. RowVectorDIMS dir_i = dir.row(i);
  1503. this->intersect_ray(V,Ele,origin_i,dir_i,hits[i]);
  1504. },
  1505. 10000);
  1506. }
  1507. template <typename DerivedV, int DIM>
  1508. template <typename DerivedEle>
  1509. IGL_INLINE bool
  1510. igl::AABB<DerivedV,DIM>::intersect_ray_opt(
  1511. const Eigen::MatrixBase<DerivedV> & V,
  1512. const Eigen::MatrixBase<DerivedEle> & Ele,
  1513. const RowVectorDIMS & origin,
  1514. const RowVectorDIMS & dir,
  1515. const RowVectorDIMS & inv_dir,
  1516. const RowVectorDIMS & inv_dir_pad,
  1517. std::vector<igl::Hit<typename DerivedV::Scalar>> & hits) const
  1518. {
  1519. hits.clear();
  1520. const Scalar t0 = 0;
  1521. const Scalar t1 = std::numeric_limits<Scalar>::infinity();
  1522. {
  1523. Scalar _1,_2;
  1524. if(!ray_box_intersect(origin,inv_dir,inv_dir_pad,m_box,t0,t1,_1,_2))
  1525. {
  1526. return false;
  1527. }
  1528. }
  1529. if(this->is_leaf())
  1530. {
  1531. // Actually process elements
  1532. assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
  1533. // Cheesecake way of hitting element
  1534. bool ret = ray_mesh_intersect(origin,dir,V,Ele.row(m_primitive),hits);
  1535. // Since we only gave ray_mesh_intersect a single face, it will have set
  1536. // any hits to id=0. Set these to this primitive's id
  1537. for(auto & hit: hits)
  1538. {
  1539. hit.id = m_primitive;
  1540. }
  1541. return ret;
  1542. }
  1543. std::vector<igl::Hit<typename DerivedV::Scalar>> left_hits;
  1544. std::vector<igl::Hit<typename DerivedV::Scalar>> right_hits;
  1545. const bool left_ret = m_left->intersect_ray_opt(V,Ele,origin,dir,inv_dir,inv_dir_pad,left_hits);
  1546. const bool right_ret = m_right->intersect_ray_opt(V,Ele,origin,dir,inv_dir,inv_dir_pad,right_hits);
  1547. hits.insert(hits.end(),left_hits.begin(),left_hits.end());
  1548. hits.insert(hits.end(),right_hits.begin(),right_hits.end());
  1549. return left_ret || right_ret;
  1550. }
  1551. template <typename DerivedV, int DIM>
  1552. template <typename DerivedEle>
  1553. IGL_INLINE bool
  1554. igl::AABB<DerivedV,DIM>::intersect_ray_opt(
  1555. const Eigen::MatrixBase<DerivedV> & V,
  1556. const Eigen::MatrixBase<DerivedEle> & Ele,
  1557. const RowVectorDIMS & origin,
  1558. const RowVectorDIMS & dir,
  1559. const RowVectorDIMS & inv_dir,
  1560. const RowVectorDIMS & inv_dir_pad,
  1561. const Scalar _min_t,
  1562. igl::Hit<typename DerivedV::Scalar> & hit) const
  1563. {
  1564. Scalar min_t = _min_t;
  1565. const Scalar t0 = 0;
  1566. {
  1567. Scalar _1,_2;
  1568. if(!ray_box_intersect(origin,inv_dir,inv_dir_pad,m_box,t0,min_t,_1,_2))
  1569. {
  1570. return false;
  1571. }
  1572. }
  1573. if(this->is_leaf())
  1574. {
  1575. // Actually process elements
  1576. assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
  1577. // Cheesecake way of hitting element
  1578. bool ret = ray_mesh_intersect(origin,dir,V,Ele.row(m_primitive),hit);
  1579. hit.id = m_primitive;
  1580. return ret;
  1581. }
  1582. // Doesn't seem like smartly choosing left before/after right makes a
  1583. // differnce
  1584. igl::Hit<typename DerivedV::Scalar> left_hit;
  1585. igl::Hit<typename DerivedV::Scalar> right_hit;
  1586. bool left_ret = m_left->intersect_ray_opt(V,Ele,origin,dir,inv_dir,inv_dir_pad,min_t,left_hit);
  1587. if(left_ret && left_hit.t<min_t)
  1588. {
  1589. // It's scary that this line doesn't seem to matter....
  1590. min_t = left_hit.t;
  1591. hit = left_hit;
  1592. left_ret = true;
  1593. }else
  1594. {
  1595. left_ret = false;
  1596. }
  1597. bool right_ret = m_right->intersect_ray_opt(V,Ele,origin,dir,inv_dir,inv_dir_pad,min_t,right_hit);
  1598. if(right_ret && right_hit.t<min_t)
  1599. {
  1600. min_t = right_hit.t;
  1601. hit = right_hit;
  1602. right_ret = true;
  1603. }else
  1604. {
  1605. right_ret = false;
  1606. }
  1607. return left_ret || right_ret;
  1608. }
  1609. #ifdef IGL_STATIC_LIBRARY
  1610. // Explicit template instantiation
  1611. // generated by autoexplicit.sh
  1612. template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, std::vector<igl::Hit<double>, std::allocator<igl::Hit<double>> >&) const;
  1613. template class igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>;
  1614. template class igl::AABB<Eigen::Matrix<double, -1, 3, 0, -1, 3>, 3>;
  1615. template class igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>;
  1616. template class igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>;
  1617. template class igl::AABB<Eigen::Matrix<double, -1, 2, 0, -1, 2>, 2>;
  1618. template igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>* igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::update_primitive<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double);
  1619. // generated by autoexplicit.sh
  1620. template double igl::AABB<Eigen::Matrix<double, -1, 3, 0, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
  1621. // generated by autoexplicit.sh
  1622. template double igl::AABB<Eigen::Matrix<double, -1, 2, 0, -1, 2>, 2>::squared_distance<Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
  1623. // generated by autoexplicit.sh
  1624. template void igl::AABB<Eigen::Matrix<double, -1, 3, 0, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
  1625. // generated by autoexplicit.sh
  1626. template void igl::AABB<Eigen::Matrix<double, -1, 2, 0, -1, 2>, 2>::init<Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&);
  1627. // generated by autoexplicit.sh
  1628. template bool igl::AABB<Eigen::Matrix<float, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, std::vector<igl::Hit<float>, std::allocator<igl::Hit<float>> >&) const;
  1629. // generated by autoexplicit.sh
  1630. template void igl::AABB<Eigen::Matrix<float, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
  1631. // generated by autoexplicit.sh
  1632. template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&) const;
  1633. // generated by autoexplicit.sh
  1634. template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
  1635. template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, igl::Hit<double>&) const;
  1636. template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
  1637. template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
  1638. template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
  1639. template double igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
  1640. template float igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
  1641. template float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
  1642. template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
  1643. template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, bool) const;
  1644. template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
  1645. template std::vector<int> igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 2, 1, 1, 2>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2>> const&, bool) const;
  1646. template std::vector<int> igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3>> const&, bool) const;
  1647. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
  1648. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
  1649. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
  1650. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
  1651. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1652. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1653. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1654. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1655. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
  1656. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
  1657. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
  1658. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
  1659. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1660. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1661. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1662. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1663. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
  1664. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<int, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&) const;
  1665. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
  1666. template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
  1667. template void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
  1668. template void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
  1669. template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
  1670. template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
  1671. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, double, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>>&);
  1672. template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, std::vector<std::vector<igl::Hit<double>, std::allocator<igl::Hit<double>>>, std::allocator<std::vector<igl::Hit<double>, std::allocator<igl::Hit<double>>>>>&);
  1673. #ifdef WIN32
  1674. template void igl::AABB<class Eigen::Matrix<double,-1,-1,0,-1,-1>,3>::squared_distance<class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,3,0,-1,3> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > &)const;
  1675. #endif
  1676. #endif