MeshLib
 
Loading...
Searching...
No Matches
MRMesh/MRBox.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMeshFwd.h"
4#include "MRAffineXf3.h"
5#include <algorithm>
6#include <cassert>
7#include <limits>
8
9namespace MR
10{
11
15
17template <typename T>
18std::array<Vector3<T>, 8> getCorners( const Box<Vector3<T>> & box );
19
21template <typename V>
22struct Box
23{
24public:
25 using T = typename V::ValueType;
26
27 V min, max;
28
30 const V & operator []( int e ) const { return *( &min + e ); }
31 V & operator []( int e ) { return *( &min + e ); }
32
34 Box() : min{ V::diagonal( std::numeric_limits<T>::max() ) }, max{ V::diagonal( std::numeric_limits<T>::lowest() ) } { }
35 explicit Box( NoInit ) : min{ noInit }, max{ noInit } { }
36 Box( const V& min, const V& max ) : min{ min }, max{ max } { }
37
38 template <typename U>
39 explicit Box( const Box<U> & a ) : min{ a.min }, max{ a.max } { }
40
41 static Box fromMinAndSize( const V& min, const V& size ) { return Box{ min,min + size }; }
42
44 bool valid() const
45 {
46 for ( int i = 0; i < V::elements; ++i )
47 if ( min[i] > max[i] )
48 return false;
49 return true;
50 }
51
53 V center() const { assert( valid() ); return ( min + max ) / T(2); }
54
56 V size() const { assert( valid() ); return max - min; }
57
59 T diagonal() const { return size().length(); }
60
62 T volume() const
63 {
64 assert( valid() );
65 T res{ 1 };
66 for ( int i = 0; i < V::elements; ++i )
67 res *= max[i] - min[i];
68 return res;
69 }
70
72 void include( const V & pt )
73 {
74 for ( int i = 0; i < V::elements; ++i )
75 {
76 if ( pt[i] < min[i] ) min[i] = pt[i];
77 if ( pt[i] > max[i] ) max[i] = pt[i];
78 }
79 }
80
82 void include( const Box & b )
83 {
84 for ( int i = 0; i < V::elements; ++i )
85 {
86 if ( b.min[i] < min[i] ) min[i] = b.min[i];
87 if ( b.max[i] > max[i] ) max[i] = b.max[i];
88 }
89 }
90
92 bool contains( const V & pt ) const
93 {
94 for ( int i = 0; i < V::elements; ++i )
95 if ( min[i] > pt[i] || pt[i] > max[i] )
96 return false;
97 return true;
98 }
99
101 V getBoxClosestPointTo( const V & pt ) const
102 {
103 assert( valid() );
104 V res;
105 for ( int i = 0; i < V::elements; ++i )
106 res[i] = std::clamp( pt[i], min[i], max[i] );
107 return res;
108 }
109
111 bool intersects( const Box & b ) const
112 {
113 for ( int i = 0; i < V::elements; ++i )
114 {
115 if ( b.max[i] < min[i] || b.min[i] > max[i] )
116 return false;
117 }
118 return true;
119 }
120
122 Box intersection( const Box & b ) const
123 {
124 Box res;
125 for ( int i = 0; i < V::elements; ++i )
126 {
127 res.min[i] = std::max( min[i], b.min[i] );
128 res.max[i] = std::min( max[i], b.max[i] );
129 }
130 return res;
131 }
132 Box & intersect( const Box & b ) { return *this = intersection( b ); }
133
136 T getDistanceSq( const Box & b ) const
137 {
138 auto ibox = intersection( b );
139 T distSq = 0;
140 for ( int i = 0; i < V::elements; ++i )
141 if ( ibox.min[i] > ibox.max[i] )
142 distSq += sqr( ibox.min[i] - ibox.max[i] );
143 return distSq;
144 }
145
148 T getDistanceSq( const V & pt ) const
149 {
150 assert( valid() );
151 T res{};
152 for ( int i = 0; i < V::elements; ++i )
153 {
154 if ( pt[i] < min[i] )
155 res += sqr( pt[i] - min[i] );
156 else
157 if ( pt[i] > max[i] )
158 res += sqr( pt[i] - max[i] );
159 }
160 return res;
161 }
162
165 {
166 assert( valid() );
167 Box res;
168 for ( int i = 0; i < V::elements; ++i )
169 {
170 res.min[i] = std::nextafter( min[i], std::numeric_limits<T>::lowest() );
171 res.max[i] = std::nextafter( max[i], std::numeric_limits<T>::max() );
172 }
173 return res;
174 }
175
176 bool operator == ( const Box & a ) const
177 { return min == a.min && max == a.max; }
178 bool operator != ( const Box & a ) const
179 { return !( *this == a ); }
180};
181
182template <typename T>
183inline std::array<Vector3<T>, 8> getCorners( const Box<Vector3<T>> & box )
184{
185 return
186 {
187 Vector3<T>{ box.min.x, box.min.y, box.min.z },
188 Vector3<T>{ box.max.x, box.min.y, box.min.z },
189 Vector3<T>{ box.min.x, box.max.y, box.min.z },
190 Vector3<T>{ box.max.x, box.max.y, box.min.z },
191 Vector3<T>{ box.min.x, box.min.y, box.max.z },
192 Vector3<T>{ box.max.x, box.min.y, box.max.z },
193 Vector3<T>{ box.min.x, box.max.y, box.max.z },
194 Vector3<T>{ box.max.x, box.max.y, box.max.z }
195 };
196}
197
198template <typename T>
199inline std::array<Vector2<T>, 4> getCorners( const Box<Vector2<T>> & box )
200{
201 return
202 {
203 Vector2<T>{ box.min.x, box.min.y },
204 Vector2<T>{ box.max.x, box.min.y },
205 Vector2<T>{ box.min.x, box.max.y },
206 Vector2<T>{ box.max.x, box.max.y }
207 };
208}
209
211template <typename V>
212inline Box<V> transformed( const Box<V> & box, const AffineXf<V> & xf )
213{
214 if ( !box.valid() )
215 return {};
216 Box<V> res;
217 for ( const auto & p : getCorners( box ) )
218 res.include( xf( p ) );
219 return res;
220}
222template <typename V>
223inline Box<V> transformed( const Box<V> & box, const AffineXf<V> * xf )
224{
225 return xf ? transformed( box, *xf ) : box;
226}
227
229template <typename V>
230inline auto width( const Box<V>& box )
231{
232 return box.max.x - box.min.x;
233}
234
236template <typename V>
237inline auto height( const Box<V>& box )
238{
239 return box.max.y - box.min.y;
240}
241
243template <typename V>
244inline auto depth( const Box<V>& box )
245{
246 return box.max.z - box.min.z;
247}
248
250
251} // namespace MR
auto width(const Box< V > &box)
returns size along x axis
Definition MRMesh/MRBox.h:230
std::array< Vector3< T >, 8 > getCorners(const Box< Vector3< T > > &box)
returns all corners of given box
Definition MRMesh/MRBox.h:183
auto height(const Box< V > &box)
returns size along y axis
Definition MRMesh/MRBox.h:237
auto depth(const Box< V > &box)
returns size along z axis
Definition MRMesh/MRBox.h:244
Box< V > transformed(const Box< V > &box, const AffineXf< V > &xf)
find the tightest box enclosing this one after transformation
Definition MRMesh/MRBox.h:212
Definition MRCameraOrientationPlugin.h:7
constexpr T sqr(T x) noexcept
Definition MRMesh/MRMeshFwd.h:613
Box
Definition MRMesh/MRMeshFwd.h:297
constexpr NoInit noInit
Definition MRMesh/MRMeshFwd.h:57
MRMESH_CLASS Vector3
Definition MRMesh/MRMeshFwd.h:136
Definition MRMesh/MRAffineXf.h:14
Box given by its min- and max- corners.
Definition MRMesh/MRBox.h:23
Box(const V &min, const V &max)
Definition MRMesh/MRBox.h:36
void include(const V &pt)
minimally increases the box to include given point
Definition MRMesh/MRBox.h:72
V getBoxClosestPointTo(const V &pt) const
returns closest point in the box to given point
Definition MRMesh/MRBox.h:101
T getDistanceSq(const Box &b) const
Definition MRMesh/MRBox.h:136
T diagonal() const
computes length from min to max
Definition MRMesh/MRBox.h:59
void include(const Box &b)
minimally increases the box to include another box
Definition MRMesh/MRBox.h:82
V max
Definition MRMesh/MRBox.h:27
Box insignificantlyExpanded() const
expands min and max to their closest representable value
Definition MRMesh/MRBox.h:164
V center() const
computes center of the box
Definition MRMesh/MRBox.h:53
T getDistanceSq(const V &pt) const
Definition MRMesh/MRBox.h:148
V size() const
computes size of the box in all dimensions
Definition MRMesh/MRBox.h:56
bool intersects(const Box &b) const
checks whether this box intersects or touches given box
Definition MRMesh/MRBox.h:111
T volume() const
computes the volume of this box
Definition MRMesh/MRBox.h:62
static Box fromMinAndSize(const V &min, const V &size)
Definition MRMesh/MRBox.h:41
Box()
create invalid box by default
Definition MRMesh/MRBox.h:34
const V & operator[](int e) const
min/max access by 0/1 index
Definition MRMesh/MRBox.h:30
bool operator!=(const Box &a) const
Definition MRMesh/MRBox.h:178
V min
Definition MRMesh/MRBox.h:27
Box intersection(const Box &b) const
computes intersection between this and other box
Definition MRMesh/MRBox.h:122
bool contains(const V &pt) const
checks whether given point is inside (including the surface) of the box
Definition MRMesh/MRBox.h:92
Box & intersect(const Box &b)
Definition MRMesh/MRBox.h:132
Box(const Box< U > &a)
Definition MRMesh/MRBox.h:39
Box(NoInit)
Definition MRMesh/MRBox.h:35
bool valid() const
true if the box contains at least one point
Definition MRMesh/MRBox.h:44
bool operator==(const Box &a) const
Definition MRMesh/MRBox.h:176
typename V::ValueType T
Definition MRMesh/MRBox.h:25
Definition MRMesh/MRMeshFwd.h:56
Definition MRVector2.h:18
T x
Definition MRVector2.h:24
Definition MRMesh/MRVector3.h:19
T x
Definition MRMesh/MRVector3.h:25