ImathBox.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. //
  6. // Axis-aligned bounding box
  7. //
  8. #ifndef INCLUDED_IMATHBOX_H
  9. #define INCLUDED_IMATHBOX_H
  10. #include "ImathExport.h"
  11. #include "ImathNamespace.h"
  12. #include "ImathVec.h"
  13. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  14. ///
  15. /// The `Box<V>` template represents an axis-aligned bounding box defined by
  16. /// minimum and maximum values of type `V`. The `min` and `max` members are
  17. /// public.
  18. ///
  19. /// The type `V` is typically an Imath vector (i.e. `V2i`, `V3f`, etc) and must
  20. /// implement an index `operator[]` that returns a type (typically as scalar)
  21. /// that supports assignment, comparison, and arithmetic operators.
  22. ///
  23. /// `V` must also provide a constructor that takes a float and/or double for
  24. /// use in initializing the box.
  25. ///
  26. /// `V` must also provide a function `V::dimensions()` which returns the
  27. /// number of dimensions in the class (since its assumed its a vector) --
  28. /// preferably, this returns a constant expression, typically 2 or 3.
  29. ///
  30. template <class V> class IMATH_EXPORT_TEMPLATE_TYPE Box
  31. {
  32. public:
  33. /// @{
  34. /// @name Direct access to bounds
  35. /// The minimum value of the box.
  36. V min;
  37. /// The maximum value of the box.
  38. V max;
  39. /// @}
  40. /// @{
  41. /// @name Constructors
  42. /// Construct an empty bounding box. This initializes the mimimum to
  43. /// std::numeric_limits<V::baseType>::max() and the maximum to
  44. /// std::numeric_limits<V::baseType>::lowest().
  45. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box() IMATH_NOEXCEPT;
  46. /// Construct a bounding box that contains a single point.
  47. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const V& point) IMATH_NOEXCEPT;
  48. /// Construct a bounding box with the given minimum and maximum values.
  49. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const V& minV, const V& maxV) IMATH_NOEXCEPT;
  50. /// @}
  51. /// @{
  52. /// @name Comparison
  53. /// Equality
  54. IMATH_HOSTDEVICE constexpr bool operator== (const Box<V>& src) const IMATH_NOEXCEPT;
  55. /// Inequality
  56. IMATH_HOSTDEVICE constexpr bool operator!= (const Box<V>& src) const IMATH_NOEXCEPT;
  57. /// @}
  58. /// @{
  59. /// @name Manipulation
  60. /// Set the box to be empty. A box is empty if the mimimum is greater
  61. /// than the maximum. makeEmpty() sets the mimimum to `V::baseTypeMax()`
  62. /// and the maximum to `V::baseTypeLowest()`.
  63. IMATH_HOSTDEVICE void makeEmpty() IMATH_NOEXCEPT;
  64. /// Extend the box to include the given point.
  65. IMATH_HOSTDEVICE void extendBy (const V& point) IMATH_NOEXCEPT;
  66. /// Extend the box to include the given box.
  67. IMATH_HOSTDEVICE void extendBy (const Box<V>& box) IMATH_NOEXCEPT;
  68. /// Make the box include the entire range of `V`.
  69. IMATH_HOSTDEVICE void makeInfinite() IMATH_NOEXCEPT;
  70. /// @}
  71. /// @{
  72. /// @name Query
  73. /// Return the size of the box. The size is of type `V`, defined
  74. /// as `(max-min)`. An empty box has a size of `V(0)`, i.e. 0 in
  75. /// each dimension.
  76. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 V size() const IMATH_NOEXCEPT;
  77. /// Return the center of the box. The center is defined as
  78. /// `(max+min)/2`. The center of an empty box is undefined.
  79. IMATH_HOSTDEVICE constexpr V center() const IMATH_NOEXCEPT;
  80. /// Return true if the given point is inside the box, false otherwise.
  81. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const V& point) const IMATH_NOEXCEPT;
  82. /// Return true if the given box is inside the box, false otherwise.
  83. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box<V>& box) const IMATH_NOEXCEPT;
  84. /// Return the major axis of the box. The major axis is the dimension with
  85. /// the greatest difference between maximum and minimum.
  86. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 unsigned int majorAxis() const IMATH_NOEXCEPT;
  87. /// Return true if the box is empty, false otherwise. An empty box's
  88. /// minimum is greater than its maximum.
  89. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const IMATH_NOEXCEPT;
  90. /// Return true if the box is larger than a single point, false otherwise.
  91. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const IMATH_NOEXCEPT;
  92. /// Return true if the box contains all points, false otherwise.
  93. /// An infinite box has a mimimum of`V::baseTypeLowest()`
  94. /// and a maximum of `V::baseTypeMax()`.
  95. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const IMATH_NOEXCEPT;
  96. /// @}
  97. };
  98. //--------------------
  99. // Convenient typedefs
  100. //--------------------
  101. /// 2D box of base type `short`.
  102. typedef Box<V2s> Box2s;
  103. /// 2D box of base type `int`.
  104. typedef Box<V2i> Box2i;
  105. /// 2D box of base type `int64_t`.
  106. typedef Box<V2i64> Box2i64;
  107. /// 2D box of base type `float`.
  108. typedef Box<V2f> Box2f;
  109. /// 2D box of base type `double`.
  110. typedef Box<V2d> Box2d;
  111. /// 3D box of base type `short`.
  112. typedef Box<V3s> Box3s;
  113. /// 3D box of base type `int`.
  114. typedef Box<V3i> Box3i;
  115. /// 3D box of base type `int64_t`.
  116. typedef Box<V3i64> Box3i64;
  117. /// 3D box of base type `float`.
  118. typedef Box<V3f> Box3f;
  119. /// 3D box of base type `double`.
  120. typedef Box<V3d> Box3d;
  121. template <class V>
  122. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<V>::Box() IMATH_NOEXCEPT
  123. {
  124. makeEmpty();
  125. }
  126. template <class V>
  127. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<V>::Box (const V& point) IMATH_NOEXCEPT
  128. {
  129. min = point;
  130. max = point;
  131. }
  132. template <class V>
  133. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<V>::Box (const V& minV, const V& maxV) IMATH_NOEXCEPT
  134. {
  135. min = minV;
  136. max = maxV;
  137. }
  138. template <class V>
  139. IMATH_HOSTDEVICE constexpr inline bool
  140. Box<V>::operator== (const Box<V>& src) const IMATH_NOEXCEPT
  141. {
  142. return (min == src.min && max == src.max);
  143. }
  144. template <class V>
  145. IMATH_HOSTDEVICE constexpr inline bool
  146. Box<V>::operator!= (const Box<V>& src) const IMATH_NOEXCEPT
  147. {
  148. return (min != src.min || max != src.max);
  149. }
  150. template <class V>
  151. IMATH_HOSTDEVICE inline void
  152. Box<V>::makeEmpty() IMATH_NOEXCEPT
  153. {
  154. min = V (V::baseTypeMax());
  155. max = V (V::baseTypeLowest());
  156. }
  157. template <class V>
  158. IMATH_HOSTDEVICE inline void
  159. Box<V>::makeInfinite() IMATH_NOEXCEPT
  160. {
  161. min = V (V::baseTypeLowest());
  162. max = V (V::baseTypeMax());
  163. }
  164. template <class V>
  165. IMATH_HOSTDEVICE inline void
  166. Box<V>::extendBy (const V& point) IMATH_NOEXCEPT
  167. {
  168. for (unsigned int i = 0; i < min.dimensions(); i++)
  169. {
  170. if (point[i] < min[i])
  171. min[i] = point[i];
  172. if (point[i] > max[i])
  173. max[i] = point[i];
  174. }
  175. }
  176. template <class V>
  177. IMATH_HOSTDEVICE inline void
  178. Box<V>::extendBy (const Box<V>& box) IMATH_NOEXCEPT
  179. {
  180. for (unsigned int i = 0; i < min.dimensions(); i++)
  181. {
  182. if (box.min[i] < min[i])
  183. min[i] = box.min[i];
  184. if (box.max[i] > max[i])
  185. max[i] = box.max[i];
  186. }
  187. }
  188. template <class V>
  189. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  190. Box<V>::intersects (const V& point) const IMATH_NOEXCEPT
  191. {
  192. for (unsigned int i = 0; i < min.dimensions(); i++)
  193. {
  194. if (point[i] < min[i] || point[i] > max[i])
  195. return false;
  196. }
  197. return true;
  198. }
  199. template <class V>
  200. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  201. Box<V>::intersects (const Box<V>& box) const IMATH_NOEXCEPT
  202. {
  203. for (unsigned int i = 0; i < min.dimensions(); i++)
  204. {
  205. if (box.max[i] < min[i] || box.min[i] > max[i])
  206. return false;
  207. }
  208. return true;
  209. }
  210. template <class V>
  211. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline V
  212. Box<V>::size() const IMATH_NOEXCEPT
  213. {
  214. if (isEmpty())
  215. return V (0);
  216. return max - min;
  217. }
  218. template <class V>
  219. IMATH_HOSTDEVICE constexpr inline V
  220. Box<V>::center() const IMATH_NOEXCEPT
  221. {
  222. return (max + min) / 2;
  223. }
  224. template <class V>
  225. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  226. Box<V>::isEmpty() const IMATH_NOEXCEPT
  227. {
  228. for (unsigned int i = 0; i < min.dimensions(); i++)
  229. {
  230. if (max[i] < min[i])
  231. return true;
  232. }
  233. return false;
  234. }
  235. template <class V>
  236. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  237. Box<V>::isInfinite() const IMATH_NOEXCEPT
  238. {
  239. for (unsigned int i = 0; i < min.dimensions(); i++)
  240. {
  241. if (min[i] != V::baseTypeLowest() || max[i] != V::baseTypeMax())
  242. return false;
  243. }
  244. return true;
  245. }
  246. template <class V>
  247. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  248. Box<V>::hasVolume() const IMATH_NOEXCEPT
  249. {
  250. for (unsigned int i = 0; i < min.dimensions(); i++)
  251. {
  252. if (max[i] <= min[i])
  253. return false;
  254. }
  255. return true;
  256. }
  257. template <class V>
  258. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline unsigned int
  259. Box<V>::majorAxis() const IMATH_NOEXCEPT
  260. {
  261. unsigned int major = 0;
  262. V s = size();
  263. for (unsigned int i = 1; i < min.dimensions(); i++)
  264. {
  265. if (s[i] > s[major])
  266. major = i;
  267. }
  268. return major;
  269. }
  270. //-------------------------------------------------------------------
  271. //
  272. // Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T>
  273. //
  274. //-------------------------------------------------------------------
  275. template <typename V> class Box;
  276. ///
  277. /// The Box<Vec2<T>> template represents a 2D bounding box defined by
  278. /// minimum and maximum values of type Vec2<T>. The min and max members are
  279. /// public.
  280. ///
  281. template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Box<Vec2<T>>
  282. {
  283. public:
  284. /// @{
  285. /// @name Direct access to bounds
  286. /// The minimum value of the box.
  287. Vec2<T> min;
  288. /// The maximum value of the box.
  289. Vec2<T> max;
  290. /// @}
  291. /// @{
  292. /// @name Constructors and Assignment
  293. /// Empty by default
  294. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box() IMATH_NOEXCEPT;
  295. /// Construct a bounding box that contains a single point.
  296. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec2<T>& point) IMATH_NOEXCEPT;
  297. /// Construct a bounding box with the given minimum and maximum points
  298. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec2<T>& minT, const Vec2<T>& maxT) IMATH_NOEXCEPT;
  299. /// @}
  300. /// @{
  301. /// @name Comparison
  302. /// Equality
  303. IMATH_HOSTDEVICE constexpr bool operator== (const Box<Vec2<T>>& src) const IMATH_NOEXCEPT;
  304. /// Inequality
  305. IMATH_HOSTDEVICE constexpr bool operator!= (const Box<Vec2<T>>& src) const IMATH_NOEXCEPT;
  306. /// @}
  307. /// @{
  308. /// @name Manipulation
  309. /// Set the Box to be empty. A Box is empty if the mimimum is
  310. /// greater than the maximum. makeEmpty() sets the mimimum to
  311. /// std::numeric_limits<T>::max() and the maximum to
  312. /// std::numeric_limits<T>::lowest().
  313. IMATH_HOSTDEVICE void makeEmpty() IMATH_NOEXCEPT;
  314. /// Extend the Box to include the given point.
  315. IMATH_HOSTDEVICE void extendBy (const Vec2<T>& point) IMATH_NOEXCEPT;
  316. /// Extend the Box to include the given box.
  317. IMATH_HOSTDEVICE void extendBy (const Box<Vec2<T>>& box) IMATH_NOEXCEPT;
  318. /// Make the box include the entire range of T.
  319. IMATH_HOSTDEVICE void makeInfinite() IMATH_NOEXCEPT;
  320. /// @}
  321. /// @{
  322. /// @name Query
  323. /// Return the size of the box. The size is of type `V`, defined as
  324. /// `(max-min)`. An empty box has a size of `V(0)`, i.e. 0 in each dimension.
  325. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2<T> size() const IMATH_NOEXCEPT;
  326. /// Return the center of the box. The center is defined as
  327. /// `(max+min)/2`. The center of an empty box is undefined.
  328. IMATH_HOSTDEVICE constexpr Vec2<T> center() const IMATH_NOEXCEPT;
  329. /// Return true if the given point is inside the box, false otherwise.
  330. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Vec2<T>& point) const IMATH_NOEXCEPT;
  331. /// Return true if the given box is inside the box, false otherwise.
  332. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box<Vec2<T>>& box) const IMATH_NOEXCEPT;
  333. /// Return the major axis of the box. The major axis is the dimension with
  334. /// the greatest difference between maximum and minimum.
  335. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 unsigned int majorAxis() const IMATH_NOEXCEPT;
  336. /// Return true if the box is empty, false otherwise. An empty box's
  337. /// minimum is greater than its maximum.
  338. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const IMATH_NOEXCEPT;
  339. /// Return true if the box is larger than a single point, false otherwise.
  340. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const IMATH_NOEXCEPT;
  341. /// Return true if the box contains all points, false otherwise.
  342. /// An infinite box has a mimimum of `V::baseTypeMin()`
  343. /// and a maximum of `V::baseTypeMax()`.
  344. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const IMATH_NOEXCEPT;
  345. /// @}
  346. };
  347. //----------------
  348. // Implementation
  349. //----------------
  350. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<Vec2<T>>::Box() IMATH_NOEXCEPT
  351. {
  352. makeEmpty();
  353. }
  354. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<Vec2<T>>::Box (const Vec2<T>& point) IMATH_NOEXCEPT
  355. {
  356. min = point;
  357. max = point;
  358. }
  359. template <class T>
  360. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<Vec2<T>>::Box (const Vec2<T>& minT, const Vec2<T>& maxT) IMATH_NOEXCEPT
  361. {
  362. min = minT;
  363. max = maxT;
  364. }
  365. template <class T>
  366. IMATH_HOSTDEVICE constexpr inline bool
  367. Box<Vec2<T>>::operator== (const Box<Vec2<T>>& src) const IMATH_NOEXCEPT
  368. {
  369. return (min == src.min && max == src.max);
  370. }
  371. template <class T>
  372. IMATH_HOSTDEVICE constexpr inline bool
  373. Box<Vec2<T>>::operator!= (const Box<Vec2<T>>& src) const IMATH_NOEXCEPT
  374. {
  375. return (min != src.min || max != src.max);
  376. }
  377. template <class T>
  378. IMATH_HOSTDEVICE inline void
  379. Box<Vec2<T>>::makeEmpty() IMATH_NOEXCEPT
  380. {
  381. min = Vec2<T> (Vec2<T>::baseTypeMax());
  382. max = Vec2<T> (Vec2<T>::baseTypeLowest());
  383. }
  384. template <class T>
  385. IMATH_HOSTDEVICE inline void
  386. Box<Vec2<T>>::makeInfinite() IMATH_NOEXCEPT
  387. {
  388. min = Vec2<T> (Vec2<T>::baseTypeLowest());
  389. max = Vec2<T> (Vec2<T>::baseTypeMax());
  390. }
  391. template <class T>
  392. IMATH_HOSTDEVICE inline void
  393. Box<Vec2<T>>::extendBy (const Vec2<T>& point) IMATH_NOEXCEPT
  394. {
  395. if (point[0] < min[0])
  396. min[0] = point[0];
  397. if (point[0] > max[0])
  398. max[0] = point[0];
  399. if (point[1] < min[1])
  400. min[1] = point[1];
  401. if (point[1] > max[1])
  402. max[1] = point[1];
  403. }
  404. template <class T>
  405. IMATH_HOSTDEVICE inline void
  406. Box<Vec2<T>>::extendBy (const Box<Vec2<T>>& box) IMATH_NOEXCEPT
  407. {
  408. if (box.min[0] < min[0])
  409. min[0] = box.min[0];
  410. if (box.max[0] > max[0])
  411. max[0] = box.max[0];
  412. if (box.min[1] < min[1])
  413. min[1] = box.min[1];
  414. if (box.max[1] > max[1])
  415. max[1] = box.max[1];
  416. }
  417. template <class T>
  418. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  419. Box<Vec2<T>>::intersects (const Vec2<T>& point) const IMATH_NOEXCEPT
  420. {
  421. if (point[0] < min[0] || point[0] > max[0] || point[1] < min[1] || point[1] > max[1])
  422. return false;
  423. return true;
  424. }
  425. template <class T>
  426. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  427. Box<Vec2<T>>::intersects (const Box<Vec2<T>>& box) const IMATH_NOEXCEPT
  428. {
  429. if (box.max[0] < min[0] || box.min[0] > max[0] || box.max[1] < min[1] || box.min[1] > max[1])
  430. return false;
  431. return true;
  432. }
  433. template <class T>
  434. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Vec2<T>
  435. Box<Vec2<T>>::size() const IMATH_NOEXCEPT
  436. {
  437. if (isEmpty())
  438. return Vec2<T> (0);
  439. return max - min;
  440. }
  441. template <class T>
  442. IMATH_HOSTDEVICE constexpr inline Vec2<T>
  443. Box<Vec2<T>>::center() const IMATH_NOEXCEPT
  444. {
  445. return (max + min) / 2;
  446. }
  447. template <class T>
  448. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  449. Box<Vec2<T>>::isEmpty() const IMATH_NOEXCEPT
  450. {
  451. if (max[0] < min[0] || max[1] < min[1])
  452. return true;
  453. return false;
  454. }
  455. template <class T>
  456. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  457. Box<Vec2<T>>::isInfinite() const IMATH_NOEXCEPT
  458. {
  459. if (min[0] != std::numeric_limits<T>::lowest() ||
  460. max[0] != std::numeric_limits<T>::max() ||
  461. min[1] != std::numeric_limits<T>::lowest() ||
  462. max[1] != std::numeric_limits<T>::max())
  463. return false;
  464. return true;
  465. }
  466. template <class T>
  467. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  468. Box<Vec2<T>>::hasVolume() const IMATH_NOEXCEPT
  469. {
  470. if (max[0] <= min[0] || max[1] <= min[1])
  471. return false;
  472. return true;
  473. }
  474. template <class T>
  475. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline unsigned int
  476. Box<Vec2<T>>::majorAxis() const IMATH_NOEXCEPT
  477. {
  478. unsigned int major = 0;
  479. Vec2<T> s = size();
  480. if (s[1] > s[major])
  481. major = 1;
  482. return major;
  483. }
  484. ///
  485. /// The Box<Vec3> template represents a 3D bounding box defined by
  486. /// minimum and maximum values of type Vec3.
  487. ///
  488. template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Box<Vec3<T>>
  489. {
  490. public:
  491. /// @{
  492. /// @name Direct access to bounds
  493. /// The minimum value of the box.
  494. Vec3<T> min;
  495. /// The maximum value of the box.
  496. Vec3<T> max;
  497. /// @}
  498. /// @{
  499. /// @name Constructors
  500. /// Empty by default
  501. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box() IMATH_NOEXCEPT;
  502. /// Construct a bounding box that contains a single point.
  503. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec3<T>& point) IMATH_NOEXCEPT;
  504. /// Construct a bounding box with the given minimum and maximum points
  505. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Box (const Vec3<T>& minT, const Vec3<T>& maxT) IMATH_NOEXCEPT;
  506. /// @}
  507. /// Equality
  508. IMATH_HOSTDEVICE constexpr bool operator== (const Box<Vec3<T>>& src) const IMATH_NOEXCEPT;
  509. /// Inequality
  510. IMATH_HOSTDEVICE constexpr bool operator!= (const Box<Vec3<T>>& src) const IMATH_NOEXCEPT;
  511. /// Set the Box to be empty. A Box is empty if the mimimum is
  512. /// greater than the maximum. makeEmpty() sets the mimimum to
  513. /// std::numeric_limits<T>::max() and the maximum to
  514. /// std::numeric_limits<T>::lowest().
  515. IMATH_HOSTDEVICE void makeEmpty() IMATH_NOEXCEPT;
  516. /// Extend the Box to include the given point.
  517. IMATH_HOSTDEVICE void extendBy (const Vec3<T>& point) IMATH_NOEXCEPT;
  518. /// Extend the Box to include the given box.
  519. IMATH_HOSTDEVICE void extendBy (const Box<Vec3<T>>& box) IMATH_NOEXCEPT;
  520. /// Make the box include the entire range of T.
  521. IMATH_HOSTDEVICE void makeInfinite() IMATH_NOEXCEPT;
  522. /// Return the size of the box. The size is of type `V`, defined as
  523. /// (max-min). An empty box has a size of V(0), i.e. 0 in each dimension.
  524. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3<T> size() const IMATH_NOEXCEPT;
  525. /// Return the center of the box. The center is defined as
  526. /// (max+min)/2. The center of an empty box is undefined.
  527. IMATH_HOSTDEVICE constexpr Vec3<T> center() const IMATH_NOEXCEPT;
  528. /// Return true if the given point is inside the box, false otherwise.
  529. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Vec3<T>& point) const IMATH_NOEXCEPT;
  530. /// Return true if the given box is inside the box, false otherwise.
  531. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects (const Box<Vec3<T>>& box) const IMATH_NOEXCEPT;
  532. /// Return the major axis of the box. The major axis is the dimension with
  533. /// the greatest difference between maximum and minimum.
  534. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 unsigned int majorAxis() const IMATH_NOEXCEPT;
  535. /// Return true if the box is empty, false otherwise. An empty box's
  536. /// minimum is greater than its maximum.
  537. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isEmpty() const IMATH_NOEXCEPT;
  538. /// Return true if the box is larger than a single point, false otherwise.
  539. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool hasVolume() const IMATH_NOEXCEPT;
  540. /// Return true if the box contains all points, false otherwise.
  541. /// An infinite box has a mimimum of`V::baseTypeMin()`
  542. /// and a maximum of `V::baseTypeMax()`.
  543. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool isInfinite() const IMATH_NOEXCEPT;
  544. };
  545. //----------------
  546. // Implementation
  547. //----------------
  548. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<Vec3<T>>::Box() IMATH_NOEXCEPT
  549. {
  550. makeEmpty();
  551. }
  552. template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<Vec3<T>>::Box (const Vec3<T>& point) IMATH_NOEXCEPT
  553. {
  554. min = point;
  555. max = point;
  556. }
  557. template <class T>
  558. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Box<Vec3<T>>::Box (const Vec3<T>& minT, const Vec3<T>& maxT) IMATH_NOEXCEPT
  559. {
  560. min = minT;
  561. max = maxT;
  562. }
  563. template <class T>
  564. IMATH_HOSTDEVICE constexpr inline bool
  565. Box<Vec3<T>>::operator== (const Box<Vec3<T>>& src) const IMATH_NOEXCEPT
  566. {
  567. return (min == src.min && max == src.max);
  568. }
  569. template <class T>
  570. IMATH_HOSTDEVICE constexpr inline bool
  571. Box<Vec3<T>>::operator!= (const Box<Vec3<T>>& src) const IMATH_NOEXCEPT
  572. {
  573. return (min != src.min || max != src.max);
  574. }
  575. template <class T>
  576. IMATH_HOSTDEVICE inline void
  577. Box<Vec3<T>>::makeEmpty() IMATH_NOEXCEPT
  578. {
  579. min = Vec3<T> (Vec3<T>::baseTypeMax());
  580. max = Vec3<T> (Vec3<T>::baseTypeLowest());
  581. }
  582. template <class T>
  583. IMATH_HOSTDEVICE inline void
  584. Box<Vec3<T>>::makeInfinite() IMATH_NOEXCEPT
  585. {
  586. min = Vec3<T> (Vec3<T>::baseTypeLowest());
  587. max = Vec3<T> (Vec3<T>::baseTypeMax());
  588. }
  589. template <class T>
  590. IMATH_HOSTDEVICE inline void
  591. Box<Vec3<T>>::extendBy (const Vec3<T>& point) IMATH_NOEXCEPT
  592. {
  593. if (point[0] < min[0])
  594. min[0] = point[0];
  595. if (point[0] > max[0])
  596. max[0] = point[0];
  597. if (point[1] < min[1])
  598. min[1] = point[1];
  599. if (point[1] > max[1])
  600. max[1] = point[1];
  601. if (point[2] < min[2])
  602. min[2] = point[2];
  603. if (point[2] > max[2])
  604. max[2] = point[2];
  605. }
  606. template <class T>
  607. IMATH_HOSTDEVICE inline void
  608. Box<Vec3<T>>::extendBy (const Box<Vec3<T>>& box) IMATH_NOEXCEPT
  609. {
  610. if (box.min[0] < min[0])
  611. min[0] = box.min[0];
  612. if (box.max[0] > max[0])
  613. max[0] = box.max[0];
  614. if (box.min[1] < min[1])
  615. min[1] = box.min[1];
  616. if (box.max[1] > max[1])
  617. max[1] = box.max[1];
  618. if (box.min[2] < min[2])
  619. min[2] = box.min[2];
  620. if (box.max[2] > max[2])
  621. max[2] = box.max[2];
  622. }
  623. template <class T>
  624. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  625. Box<Vec3<T>>::intersects (const Vec3<T>& point) const IMATH_NOEXCEPT
  626. {
  627. if (point[0] < min[0] || point[0] > max[0] || point[1] < min[1] || point[1] > max[1] ||
  628. point[2] < min[2] || point[2] > max[2])
  629. return false;
  630. return true;
  631. }
  632. template <class T>
  633. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  634. Box<Vec3<T>>::intersects (const Box<Vec3<T>>& box) const IMATH_NOEXCEPT
  635. {
  636. if (box.max[0] < min[0] || box.min[0] > max[0] || box.max[1] < min[1] || box.min[1] > max[1] ||
  637. box.max[2] < min[2] || box.min[2] > max[2])
  638. return false;
  639. return true;
  640. }
  641. template <class T>
  642. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Vec3<T>
  643. Box<Vec3<T>>::size() const IMATH_NOEXCEPT
  644. {
  645. if (isEmpty())
  646. return Vec3<T> (0);
  647. return max - min;
  648. }
  649. template <class T>
  650. IMATH_HOSTDEVICE constexpr inline Vec3<T>
  651. Box<Vec3<T>>::center() const IMATH_NOEXCEPT
  652. {
  653. return (max + min) / 2;
  654. }
  655. template <class T>
  656. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  657. Box<Vec3<T>>::isEmpty() const IMATH_NOEXCEPT
  658. {
  659. if (max[0] < min[0] || max[1] < min[1] || max[2] < min[2])
  660. return true;
  661. return false;
  662. }
  663. template <class T>
  664. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  665. Box<Vec3<T>>::isInfinite() const IMATH_NOEXCEPT
  666. {
  667. if (min[0] != std::numeric_limits<T>::lowest() ||
  668. max[0] != std::numeric_limits<T>::max() ||
  669. min[1] != std::numeric_limits<T>::lowest() ||
  670. max[1] != std::numeric_limits<T>::max() ||
  671. min[2] != std::numeric_limits<T>::lowest() ||
  672. max[2] != std::numeric_limits<T>::max())
  673. return false;
  674. return true;
  675. }
  676. template <class T>
  677. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  678. Box<Vec3<T>>::hasVolume() const IMATH_NOEXCEPT
  679. {
  680. if (max[0] <= min[0] || max[1] <= min[1] || max[2] <= min[2])
  681. return false;
  682. return true;
  683. }
  684. template <class T>
  685. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline unsigned int
  686. Box<Vec3<T>>::majorAxis() const IMATH_NOEXCEPT
  687. {
  688. unsigned int major = 0;
  689. Vec3<T> s = size();
  690. if (s[1] > s[major])
  691. major = 1;
  692. if (s[2] > s[major])
  693. major = 2;
  694. return major;
  695. }
  696. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  697. #endif // INCLUDED_IMATHBOX_H