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