Branch data Line data Source code
1 : : #ifndef BOUND_BOX_HPP
2 : : #define BOUND_BOX_HPP
3 : :
4 : : #include "moab/Interface.hpp"
5 : : #include "moab/CartVect.hpp"
6 : :
7 : : #include <cfloat>
8 : :
9 : : namespace moab
10 : : {
11 : :
12 : : class BoundBox
13 : : {
14 : : public:
15 : 82090 : BoundBox() : bMin( DBL_MAX ), bMax( -DBL_MAX ) {}
16 : 63763 : BoundBox( const CartVect& min, const CartVect& max ) : bMin( min ), bMax( max ) {}
17 : : BoundBox( const double* corners );
18 : : // constructor used in element maps
19 : : BoundBox( std::vector< CartVect > points ) : bMin( DBL_MAX ), bMax( -DBL_MAX )
20 : : {
21 : : for( size_t i = 0; i < points.size(); i++ )
22 : : {
23 : : update_min( points[i].array() );
24 : : update_max( points[i].array() );
25 : : }
26 : : }
27 : 136666 : ~BoundBox() {}
28 : :
29 : : bool contains_point( const double* point, const double tol = 0.0 ) const;
30 : : bool intersects_box( const BoundBox& b, const double tol = 0.0 ) const;
31 : : void compute_center( CartVect& center );
32 : : void update( const BoundBox& other_box );
33 : : void update( const double* coords );
34 : : ErrorCode update( Interface& iface, const Range& elems, bool spherical = false, double radius = 1. );
35 : : ErrorCode update( Interface& iface, const EntityHandle ent, bool spherical = false, double radius = 1. );
36 : : void update_min( const BoundBox& other_box );
37 : : void update_min( const double* coords );
38 : : void update_max( const BoundBox& other_box );
39 : : void update_max( const double* coords );
40 : : ErrorCode get( double* coords );
41 : : /** in case of spherical elements, account for curvature if needed
42 : : */
43 : : void update_box_spherical_elem( const CartVect* coordverts, int len, double radius );
44 : :
45 : : /** \brief Return the diagonal length of this box
46 : : */
47 : : double diagonal_length() const;
48 : :
49 : : /** \brief Return the square of the diagonal length of this box
50 : : */
51 : : double diagonal_squared() const;
52 : :
53 : : /** \brief Return square of distance from box, or zero if inside
54 : : * \param from_point Point from which you want distance_sq
55 : : */
56 : : double distance_squared( const double* from_point ) const;
57 : :
58 : : /** \brief Return distance from box, or zero if inside
59 : : * \param from_point Point from which you want distance
60 : : */
61 : : double distance( const double* from_point ) const;
62 : :
63 : 70749 : BoundBox& operator=( const BoundBox& from )
64 : : {
65 : 70749 : bMin = from.bMin;
66 : 70749 : bMax = from.bMax;
67 : 70749 : return *this;
68 : : }
69 : 0 : inline bool operator==( const BoundBox& box ) const
70 : : {
71 [ # # ][ # # ]: 0 : return ( bMin == box.bMin && bMax == box.bMax );
72 : : }
73 : :
74 : : CartVect bMin, bMax;
75 : : };
76 : :
77 : 4 : inline BoundBox::BoundBox( const double* corners )
78 : : {
79 : : // relies on CartVect being Plain Old Data, no virtual table
80 : 2 : double* arr = bMin.array();
81 [ + + ]: 14 : for( int i = 0; i < 6; i++ )
82 : 12 : arr[i] = corners[i];
83 : 2 : }
84 : :
85 : 37154 : inline bool BoundBox::contains_point( const double* point, const double tol ) const
86 : : {
87 [ + + ][ + + ]: 138816 : if( point[0] < bMin[0] - tol || point[0] > bMax[0] + tol || point[1] < bMin[1] - tol || point[1] > bMax[1] + tol ||
[ + + + + ]
[ + + ]
88 [ + + ][ + + ]: 101662 : point[2] < bMin[2] - tol || point[2] > bMax[2] + tol )
89 : 12048 : return false;
90 : : else
91 : 25106 : return true;
92 : : }
93 : :
94 : 39688 : inline bool BoundBox::intersects_box( const BoundBox& b, const double tol ) const
95 : : {
96 [ + + ]: 158745 : if( b.bMax[0] < bMin[0] - tol || b.bMin[0] > bMax[0] + tol || b.bMax[1] < bMin[1] - tol ||
[ + - + - ]
[ + + ]
97 [ + + ][ + - ]: 119057 : b.bMin[1] > bMax[1] + tol || b.bMax[2] < bMin[2] - tol || b.bMin[2] > bMax[2] + tol )
[ - + ]
98 : 4 : return false;
99 : :
100 : : else
101 : 39684 : return true;
102 : : }
103 : :
104 : 37385 : inline void BoundBox::update( const BoundBox& other_box )
105 : : {
106 : 37385 : update_min( other_box );
107 : 37385 : update_max( other_box );
108 : 37385 : }
109 : :
110 : 5833 : inline void BoundBox::update( const double* coords )
111 : : {
112 : 5833 : update_min( coords );
113 : 5833 : update_max( coords + 3 );
114 : 5833 : }
115 : :
116 : 37385 : inline void BoundBox::update_min( const BoundBox& other_box )
117 : : {
118 [ + - ][ + - ]: 37385 : bMin[0] = std::min( bMin[0], other_box.bMin[0] );
119 [ + - ][ + - ]: 37385 : bMin[1] = std::min( bMin[1], other_box.bMin[1] );
120 [ + - ][ + - ]: 37385 : bMin[2] = std::min( bMin[2], other_box.bMin[2] );
121 : 37385 : }
122 : :
123 : 36887 : inline void BoundBox::update_min( const double* coords )
124 : : {
125 : 36887 : bMin[0] = std::min( bMin[0], coords[0] );
126 : 36887 : bMin[1] = std::min( bMin[1], coords[1] );
127 : 36887 : bMin[2] = std::min( bMin[2], coords[2] );
128 : 36887 : }
129 : :
130 : 37385 : inline void BoundBox::update_max( const BoundBox& other_box )
131 : : {
132 [ + - ][ + - ]: 37385 : bMax[0] = std::max( bMax[0], other_box.bMax[0] );
133 [ + - ][ + - ]: 37385 : bMax[1] = std::max( bMax[1], other_box.bMax[1] );
134 [ + - ][ + - ]: 37385 : bMax[2] = std::max( bMax[2], other_box.bMax[2] );
135 : 37385 : }
136 : :
137 : 36887 : inline void BoundBox::update_max( const double* coords )
138 : : {
139 : 36887 : bMax[0] = std::max( bMax[0], coords[0] );
140 : 36887 : bMax[1] = std::max( bMax[1], coords[1] );
141 : 36887 : bMax[2] = std::max( bMax[2], coords[2] );
142 : 36887 : }
143 : :
144 : 0 : inline ErrorCode BoundBox::get( double* coords )
145 : : {
146 : 0 : bMin.get( coords );
147 : 0 : bMax.get( coords + 3 );
148 : 0 : return MB_SUCCESS;
149 : : }
150 : :
151 : 1 : inline void BoundBox::compute_center( CartVect& center )
152 : : {
153 [ + - ]: 1 : center = 0.5 * ( bMin + bMax );
154 : 1 : }
155 : :
156 : 0 : inline std::ostream& operator<<( std::ostream& out, const BoundBox& box )
157 : : {
158 [ # # ][ # # ]: 0 : out << ( std::string ) "Min: ";
159 : 0 : out << box.bMin;
160 [ # # ][ # # ]: 0 : out << ( std::string ) ", Max: ";
161 : 0 : out << box.bMax;
162 : 0 : return out;
163 : : }
164 : :
165 : 2 : inline ErrorCode BoundBox::update( Interface& iface, const EntityHandle ent, bool spherical, double radius )
166 : : {
167 [ + - ]: 2 : Range tmp_range( ent, ent );
168 [ + - ]: 2 : return update( iface, tmp_range, spherical, radius );
169 : : }
170 : :
171 : 6 : inline double BoundBox::distance_squared( const double* from_point ) const
172 : : {
173 : 6 : double dist_sq = 0.0;
174 [ + + ]: 24 : for( int i = 0; i < 3; ++i )
175 : : {
176 [ - + ]: 18 : if( from_point[i] < bMin[i] )
177 : 0 : dist_sq += ( bMin[i] - from_point[i] ) * ( bMin[i] - from_point[i] );
178 [ + + ]: 18 : else if( from_point[i] > bMax[i] )
179 : 12 : dist_sq += ( bMax[i] - from_point[i] ) * ( bMax[i] - from_point[i] );
180 : : }
181 : 6 : return dist_sq;
182 : : }
183 : :
184 : 3 : inline double BoundBox::distance( const double* from_point ) const
185 : : {
186 : 3 : double dist_sq = distance_squared( from_point );
187 : 3 : return sqrt( dist_sq );
188 : : }
189 : :
190 : 3 : inline double BoundBox::diagonal_length() const
191 : : {
192 [ + - ][ + - ]: 6 : if( DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] || DBL_MAX == bMin[0] || DBL_MAX == bMin[1] ||
[ + - ][ + - ]
[ + - - + ]
[ - + ]
193 : 3 : DBL_MAX == bMin[2] )
194 : 0 : return DBL_MAX;
195 [ + - ]: 3 : return ( bMax - bMin ).length();
196 : : }
197 : :
198 : 1 : inline double BoundBox::diagonal_squared() const
199 : : {
200 [ + - ][ + - ]: 2 : if( DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] || DBL_MAX == bMin[0] || DBL_MAX == bMin[1] ||
[ + - ][ + - ]
[ + - - + ]
[ - + ]
201 : 1 : DBL_MAX == bMin[2] )
202 : 0 : return DBL_MAX;
203 [ + - ]: 1 : return ( bMax - bMin ).length_squared();
204 : : }
205 : :
206 : : } // namespace moab
207 : :
208 : : #endif
|