1 // Copyright (c) 2004 Max-Planck-Institute Saarbruecken (Germany). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org). 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h $ 7 // $Id: Box_d.h 3e03d50 2021-05-05T15:32:22+02:00 Maxime Gimeno 8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // 11 // Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de> 12 // Andreas Meyer <ameyer@mpi-sb.mpg.de> 13 14 #ifndef CGAL_BOX_INTERSECTION_D_BOX_D_H 15 #define CGAL_BOX_INTERSECTION_D_BOX_D_H 16 17 #include <CGAL/license/Box_intersection_d.h> 18 19 20 #include <CGAL/basic.h> 21 #include <CGAL/Bbox_2.h> 22 #include <CGAL/Bbox_3.h> 23 #include <CGAL/Box_intersection_d/box_limits.h> 24 25 #include <algorithm> 26 #include <array> 27 #include <atomic> 28 29 namespace CGAL { 30 31 namespace Box_intersection_d { 32 33 // Pseudo template class to skip the need for a C file for the static counter 34 template <class Dummy> 35 struct Unique_numbers { 36 typedef std::size_t ID; Unique_numbersUnique_numbers37 Unique_numbers() { 38 #ifdef CGAL_NO_ATOMIC 39 static std::size_t n = 0; 40 #else 41 static std::atomic<std::size_t> n; // initialized to 0 42 #endif 43 i = n++; 44 } idUnique_numbers45 std::size_t id() const { return i; } 46 private: 47 48 std::size_t i; 49 }; 50 51 52 53 // Policies for id-number of boxes 54 struct ID_NONE {}; 55 struct ID_EXPLICIT {}; 56 struct ID_FROM_BOX_ADDRESS {}; 57 struct ID_FROM_HANDLE {}; 58 59 // Generic template signature of boxes, specialized for policies 60 template<class NT_, int N, class IdPolicy = ID_EXPLICIT> 61 class Box_d; 62 63 // ID_NONE is used as base class and cannot be used directly in the algorithms 64 template<class NT_, int N> 65 class Box_d< NT_, N, ID_NONE> { 66 protected: 67 std::array<NT_,N> lo; 68 std::array<NT_,N> hi; 69 70 public: 71 typedef NT_ NT; 72 typedef std::size_t ID; 73 Box_d()74 Box_d() {} Box_d(bool complete)75 Box_d(bool complete) { init(complete); } Box_d(NT l[N],NT h[N])76 Box_d(NT l[N], NT h[N]) { 77 std::copy( l, l + N, &lo[0] ); 78 std::copy( h, h + N, &hi[0] ); 79 } 80 void init (bool complete = false) { 81 NT inf = box_limits<NT>::inf(); 82 NT sup = box_limits<NT>::sup(); 83 if(!complete) 84 std::swap(inf,sup); 85 std::fill( lo, lo+N, inf ); 86 std::fill( hi, hi+N, sup ); 87 } extend(NT p[N])88 void extend(NT p[N]) { 89 for( int dim = 0; dim < N; ++dim ) { 90 lo[dim] = (std::min)( lo[dim], p[dim] ); 91 hi[dim] = (std::max)( hi[dim], p[dim] ); 92 } 93 } extend(std::pair<NT,NT> p[N])94 void extend(std::pair<NT,NT> p[N]) { 95 for( int dim = 0; dim < N; ++dim ) { 96 lo[dim] = (std::min)( lo[dim], p[dim].first ); 97 hi[dim] = (std::max)( hi[dim], p[dim].second ); 98 } 99 } dimension()100 static int dimension() { return N; } min_coord(int dim)101 NT min_coord(int dim) const { return lo[dim]; } max_coord(int dim)102 NT max_coord(int dim) const { return hi[dim]; } 103 }; 104 105 // Specialization for Bbox_2, i.e. double and dim 2. 106 template<> 107 class Box_d< double, 2, ID_NONE> { 108 protected: 109 Bbox_2 bbx; 110 public: 111 typedef double NT; 112 typedef std::size_t ID; 113 Box_d()114 Box_d() {} Box_d(bool complete)115 Box_d(bool complete) { init(complete); } Box_d(NT l[2],NT h[2])116 Box_d(NT l[2], NT h[2]) : bbx(l[0], l[1], h[0], h[1]) {} Box_d(const Bbox_2 & b)117 Box_d( const Bbox_2& b) : bbx( b) {} bbox()118 const Bbox_2& bbox() const { return bbx; } init()119 void init () { 120 NT inf = box_limits<NT>::inf(); 121 NT sup = box_limits<NT>::sup(); 122 bbx = Bbox_2( sup, sup, inf, inf); 123 } init(bool complete)124 void init (bool complete) { 125 NT inf = box_limits<NT>::inf(); 126 NT sup = box_limits<NT>::sup(); 127 if ( complete) 128 bbx = Bbox_2( inf, inf, sup, sup); 129 else 130 bbx = Bbox_2( sup, sup, inf, inf); 131 } extend(NT p[2])132 void extend(NT p[2]) { 133 bbx = Bbox_2( 134 (std::min)( bbx.xmin(), p[0]), 135 (std::min)( bbx.ymin(), p[1]), 136 (std::max)( bbx.xmax(), p[0]), 137 (std::max)( bbx.ymax(), p[1])); 138 } extend(std::pair<NT,NT> p[2])139 void extend(std::pair<NT,NT> p[2]) { 140 bbx = Bbox_2( 141 (std::min)( bbx.xmin(), p[0].first), 142 (std::min)( bbx.ymin(), p[1].first), 143 (std::max)( bbx.xmax(), p[0].second), 144 (std::max)( bbx.ymax(), p[1].second)); 145 } dimension()146 static int dimension() { return 2; } min_coord(int dim)147 NT min_coord(int dim) const { return (dim==0) ? bbx.xmin() : bbx.ymin();} max_coord(int dim)148 NT max_coord(int dim) const { return (dim==0) ? bbx.xmax() : bbx.ymax();} 149 }; 150 151 // Specialization for Bbox_3, i.e. double and dim 3. 152 template<> 153 class Box_d< double, 3, ID_NONE> { 154 protected: 155 Bbox_3 bbx; 156 public: 157 typedef double NT; 158 typedef std::size_t ID; 159 Box_d()160 Box_d() {} Box_d(bool complete)161 Box_d(bool complete) { init(complete); } Box_d(NT l[3],NT h[3])162 Box_d(NT l[3], NT h[3]) : bbx(l[0], l[1], l[2], h[0], h[1], h[2]) {} Box_d(const Bbox_3 & b)163 Box_d( const Bbox_3& b) : bbx( b) {} bbox()164 const Bbox_3& bbox() const { return bbx; } init()165 void init () { 166 NT inf = box_limits<NT>::inf(); 167 NT sup = box_limits<NT>::sup(); 168 bbx = Bbox_3( sup, sup, sup, inf, inf, inf); 169 } init(bool complete)170 void init (bool complete) { 171 NT inf = box_limits<NT>::inf(); 172 NT sup = box_limits<NT>::sup(); 173 if ( complete) 174 bbx = Bbox_3( inf, inf, inf, sup, sup, sup); 175 else 176 bbx = Bbox_3( sup, sup, sup, inf, inf, inf); 177 } extend(NT p[3])178 void extend(NT p[3]) { 179 bbx = Bbox_3( 180 (std::min)( bbx.xmin(), p[0]), 181 (std::min)( bbx.ymin(), p[1]), 182 (std::min)( bbx.zmin(), p[2]), 183 (std::max)( bbx.xmax(), p[0]), 184 (std::max)( bbx.ymax(), p[1]), 185 (std::max)( bbx.zmax(), p[2])); 186 } extend(std::pair<NT,NT> p[3])187 void extend(std::pair<NT,NT> p[3]) { 188 bbx = Bbox_3( 189 (std::min)( bbx.xmin(), p[0].first), 190 (std::min)( bbx.ymin(), p[1].first), 191 (std::min)( bbx.zmin(), p[2].first), 192 (std::max)( bbx.xmax(), p[0].second), 193 (std::max)( bbx.ymax(), p[1].second), 194 (std::max)( bbx.zmax(), p[2].second)); 195 } dimension()196 static int dimension() { return 3; } min_coord(int dim)197 NT min_coord(int dim) const { 198 return (dim==0) ? bbx.xmin() : ((dim==1) ? bbx.ymin() : bbx.zmin()); 199 } max_coord(int dim)200 NT max_coord(int dim) const { 201 return (dim==0) ? bbx.xmax() : ((dim==1) ? bbx.ymax() : bbx.zmax()); 202 } 203 }; 204 205 // ID_EXPLICIT 206 template<class NT_, int N> 207 class Box_d< NT_, N, ID_EXPLICIT> : public Box_d< NT_, N, ID_NONE>, 208 public Unique_numbers<int> { 209 public: 210 typedef Box_d< NT_, N, ID_NONE> Base; 211 typedef NT_ NT; 212 typedef typename Unique_numbers<int>::ID ID; Box_d()213 Box_d() {} Box_d(bool complete)214 Box_d(bool complete) : Base(complete) {} Box_d(NT l[N],NT h[N])215 Box_d(NT l[N], NT h[N]) : Base( l, h) {} Box_d(const Bbox_2 & b)216 Box_d( const Bbox_2& b) : Base( b) {} Box_d(const Bbox_3 & b)217 Box_d( const Bbox_3& b) : Base( b) {} 218 }; 219 220 // ID_FROM_BOX_ADDRESS 221 template<class NT_, int N> 222 class Box_d< NT_, N, ID_FROM_BOX_ADDRESS> : public Box_d< NT_, N, ID_NONE> { 223 public: 224 typedef Box_d< NT_, N, ID_NONE> Base; 225 typedef NT_ NT; 226 typedef std::size_t ID; 227 Box_d()228 Box_d() {} Box_d(bool complete)229 Box_d(bool complete) : Base(complete) {} Box_d(NT l[N],NT h[N])230 Box_d(NT l[N], NT h[N]) : Base( l, h) {} Box_d(const Bbox_2 & b)231 Box_d( const Bbox_2& b) : Base( b) {} Box_d(const Bbox_3 & b)232 Box_d( const Bbox_3& b) : Base( b) {} id()233 ID id() const { return reinterpret_cast<ID>(this); } 234 }; 235 236 237 } // end namespace Box_intersection_d 238 239 240 } //namespace CGAL 241 242 #endif 243