HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_BoundingRect.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_BoundingRect.h (UT Library, C++)
7  *
8  * COMMENTS: Bounding Rectangle (floating point)
9  */
10 
11 #ifndef __UT_BoundingRect_H__
12 #define __UT_BoundingRect_H__
13 
14 #include "UT_API.h"
15 #include "UT_Assert.h"
16 #include "UT_Vector2.h"
17 
18 #include <SYS/SYS_Math.h>
19 
20 #include <iosfwd>
21 
22 
23 class UT_JSONWriter;
24 class UT_JSONValue;
25 class UT_JSONParser;
26 
27 template <typename T>
29 {
30 public:
32 
35  {
36  vals[0][0] = xmin;
37  vals[1][0] = ymin;
38  vals[0][1] = xmax;
39  vals[1][1] = ymax;
40  }
41 
42  UT_BoundingRectT(const UT_Vector2T<T> &lowerbound,
43  const UT_Vector2T<T> &upperbound)
44  {
45  vals[0][0] = lowerbound.vec[0];
46  vals[0][1] = upperbound.vec[0];
47  vals[1][0] = lowerbound.vec[1];
48  vals[1][1] = upperbound.vec[1];
49  }
50 
51  template<typename U>
53  {
54  vals[0][0] = T(src.vals[0][0]);
55  vals[0][1] = T(src.vals[0][1]);
56  vals[1][0] = T(src.vals[1][0]);
57  vals[1][1] = T(src.vals[1][1]);
58  }
59 
60  T operator()(unsigned m, unsigned n) const
61  {
62  UT_ASSERT_P( m < 2 && n < 2 );
63  return vals[m][n];
64  }
65  T &operator()(unsigned m, unsigned n)
66  {
67  UT_ASSERT_P( m < 2 && n < 2 );
68  return vals[m][n];
69  }
70 
71  int operator==(const UT_BoundingRectT<T> &brect) const
72  {
73  return (vals[0][0] == brect.vals[0][0] &&
74  vals[0][1] == brect.vals[0][1] &&
75  vals[1][0] == brect.vals[1][0] &&
76  vals[1][1] == brect.vals[1][1] );
77  }
78  bool operator!=(const UT_BoundingRectT<T> &brect) const
79  {
80  return !(*this == brect);
81  }
82 
83  int contains(const UT_Vector2T<T> &pt) const
84  {
85  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
86  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
87  return 1;
88  }
89  int contains(const UT_Vector2T<T> &pt, T tol) const
90  {
91  if (vals[0][0] > pt.x() + tol ||
92  vals[0][1] < pt.x() - tol)
93  return 0;
94  if (vals[1][0] > pt.y() + tol ||
95  vals[1][1] < pt.y() - tol)
96  return 0;
97  return 1;
98  }
99  int contains(T x, T y) const
100  {
101  return (x >= vals[0][0] && x <= vals[0][1] &&
102  y >= vals[1][0] && y <= vals[1][1] );
103  }
105  {
106  UT_Vector2T<T> closest_pt(pt.x(), pt.y());
107 
108  if (closest_pt.x() < xmin())
109  closest_pt.x() = xmin();
110  else if (closest_pt.x() > xmax())
111  closest_pt.x() = xmax();
112 
113  if (closest_pt.y() < ymin())
114  closest_pt.y() = ymin();
115  else if (closest_pt.y() > ymax())
116  closest_pt.y() = ymax();
117 
118  return closest_pt;
119  }
120 
121  int isInside(const UT_BoundingRectT<T> &brect) const
122  {
123  // are we inside brect?
124  return (vals[0][0] >= brect.vals[0][0] &&
125  vals[0][1] <= brect.vals[0][1] &&
126  vals[1][0] >= brect.vals[1][0] &&
127  vals[1][1] <= brect.vals[1][1] );
128  }
129 
130  // Determine whether a triangle defined by (v0, v1, v2) intersects the rect
131  inline int intersects(const UT_Vector2T<T> &v0,
132  const UT_Vector2T<T> &v1,
133  const UT_Vector2T<T> &v2) const;
134  // Determine whether a line between v0 & v1 intersects the rect
135  inline int intersects(const UT_Vector2T<T> &v0,
136  const UT_Vector2T<T> &v1) const;
137  inline int intersects(const UT_BoundingRectT<T> &rect) const
138  {
139  if (vals[0][0] > rect.vals[0][1] ||
140  vals[0][1] < rect.vals[0][0])
141  return 0;
142  if (vals[1][0] > rect.vals[1][1] ||
143  vals[1][1] < rect.vals[1][0])
144  return 0;
145  return 1;
146  }
147  inline int intersects(const UT_BoundingRectT<T> &rect, T tol) const
148  {
149  if (vals[0][0] > rect.vals[0][1] + tol ||
150  vals[0][1] < rect.vals[0][0] - tol)
151  return 0;
152  if (vals[1][0] > rect.vals[1][1] + tol ||
153  vals[1][1] < rect.vals[1][0] - tol)
154  return 0;
155  return 1;
156  }
157 
159  {
160  if (!intersects(src))
161  return false;
162  intersectBounds(src);
163  return true;
164  }
166  {
167  vals[0][0] = SYSmax(vals[0][0], src.vals[0][0]);
168  vals[0][1] = SYSmin(vals[0][1], src.vals[0][1]);
169  vals[1][0] = SYSmax(vals[1][0], src.vals[1][0]);
170  vals[1][1] = SYSmin(vals[1][1], src.vals[1][1]);
171  }
172  void clampX(T min, T max)
173  {
174  vals[0][0] = SYSmax(vals[0][0], min);
175  vals[0][1] = SYSmin(vals[0][1], max);
176  }
177  void clampY(T min, T max)
178  {
179  vals[1][0] = SYSmax(vals[1][0], min);
180  vals[1][1] = SYSmin(vals[1][1], max);
181  }
182 
183  /// Check whether the bounding box contains at least one point.
184  bool isValid() const
185  {
186  return vals[0][0] <= vals[0][1] &&
187  vals[1][0] <= vals[1][1];
188  }
189  void makeInvalid() { initBounds(); }
190 
191  /// Initialize the box such that
192  /// - No points are contained in the box
193  /// - The box occupies no position in space
194  void initBounds()
195  {
196  vals[0][0] =
197  vals[1][0] =
199  vals[0][1] =
200  vals[1][1] =
202  }
203  void initBounds(const UT_Vector2T<T> &pt)
204  {
205  vals[0][0] = vals[0][1] = pt.x();
206  vals[1][0] = vals[1][1] = pt.y();
207  }
208  void initBounds(T x, T y)
209  {
210  vals[0][0] = vals[0][1] = x;
211  vals[1][0] = vals[1][1] = y;
212  }
214  {
215  vals[0][0] = xmin; vals[0][1] = xmax;
216  vals[1][0] = ymin; vals[1][1] = ymax;
217  }
218  void initBounds(const fpreal32 *v) { initBounds(v[0], v[1]); }
219  void initBounds(const fpreal64 *v) { initBounds(v[0], v[1]); }
220  void initBounds(const UT_BoundingRectT<T> &rect)
221  {
222  vals[0][0] = rect.vals[0][0];
223  vals[0][1] = rect.vals[0][1];
224  vals[1][0] = rect.vals[1][0];
225  vals[1][1] = rect.vals[1][1];
226  }
227 
228  /// Initialize the box to the largest size
230  {
231  vals[0][0] = vals[1][0] =
233  vals[0][1] = vals[1][1] =
235  }
236 
238  {
239  enlargeBounds(pt.x(), pt.y());
240  }
241  void enlargeBounds(T x, T y)
242  {
243  vals[0][0] = SYSmin(vals[0][0], x);
244  vals[0][1] = SYSmax(vals[0][1], x);
245  vals[1][0] = SYSmin(vals[1][0], y);
246  vals[1][1] = SYSmax(vals[1][1], y);
247  }
248  void enlargeBounds(const fpreal32 *v) { enlargeBounds(v[0], v[1]); }
249  void enlargeBounds(const fpreal64 *v) { enlargeBounds(v[0], v[1]); }
251  {
252  vals[0][0] = SYSmin(vals[0][0], xmin);
253  vals[0][1] = SYSmax(vals[0][1], xmax);
254  vals[1][0] = SYSmin(vals[1][0], ymin);
255  vals[1][1] = SYSmax(vals[1][1], ymax);
256  }
258  {
259  vals[0][0] = SYSmin(vals[0][0], rect(0, 0));
260  vals[0][1] = SYSmax(vals[0][1], rect(0, 1));
261  vals[1][0] = SYSmin(vals[1][0], rect(1, 0));
262  vals[1][1] = SYSmax(vals[1][1], rect(1, 1));
263  }
264  void expandBounds(T dx, T dy)
265  {
266  vals[0][0] -= dx;
267  vals[0][1] += dx;
268  vals[1][0] -= dy;
269  vals[1][1] += dy;
270  }
271  void stretch(T percent = 0.001, T min = 0.001)
272  {
273  T d;
274  d = min + sizeX()*percent;
275  vals[0][0] -= d; vals[0][1] += d;
276  d = min + sizeY()*percent;
277  vals[1][0] -= d; vals[1][1] += d;
278  }
279  void translate(T x, T y)
280  {
281  vals[0][0] += x;
282  vals[0][1] += x;
283  vals[1][0] += y;
284  vals[1][1] += y;
285  }
286  void scale(T xscale, T yscale)
287  {
288  vals[0][0] *= xscale; vals[0][1] *= xscale;
289  vals[1][0] *= yscale; vals[1][1] *= yscale;
290  }
291 
293  {
294  int flag = 0;
295 
296  if (xmin() > box.xmax())
297  flag |= 0x01;
298  else if (xmax() < box.xmin())
299  flag |= 0x02;
300 
301  if (ymin() > box.ymax())
302  flag |= 0x04;
303  else if (ymax() < box.ymin())
304  flag |= 0x08;
305 
306  return flag;
307  }
308 
309  T sizeX() const { return vals[0][1] - vals[0][0]; }
310  T sizeY() const { return vals[1][1] - vals[1][0]; }
311 
312  T centerX() const { return (vals[0][0] + vals[0][1]) * 0.5; }
313  T centerY() const { return (vals[1][0] + vals[1][1]) * 0.5; }
314 
315  // projects (x,y) orthogonally to the closest point on the rectangle.
316  // Result is stored back into x and y. If valid addresses are passed into
317  // touchx and touchy, then, the values in those addresses would indicate
318  // if the new (x,y) now touches the x edges or y edges of the rectangle.
319  inline void project(T &x, T &y, int *touchx=0, int *touchy=0) const;
320 
321  T LX() const { return vals[0][0]; }
322  T LY() const { return vals[1][0]; }
323  T UX() const { return vals[0][1]; }
324  T UY() const { return vals[1][1]; }
325 
326  T &LX() { return vals[0][0]; }
327  T &LY() { return vals[1][0]; }
328  T &UX() { return vals[0][1]; }
329  T &UY() { return vals[1][1]; }
330 
331  void setX0(T v) { vals[0][0] = v; }
332  void setX1(T v) { vals[0][1] = v; }
333  void setY0(T v) { vals[1][0] = v; }
334  void setY1(T v) { vals[1][1] = v; }
335 
336  T getX0() const { return vals[0][0]; }
337  T getX1() const { return vals[0][1]; }
338  T getY0() const { return vals[1][0]; }
339  T getY1() const { return vals[1][1]; }
340 
341  T &getX0() { return vals[0][0]; }
342  T &getX1() { return vals[0][1]; }
343  T &getY0() { return vals[1][0]; }
344  T &getY1() { return vals[1][1]; }
345 
346  T xmin() const { return vals[0][0]; }
347  T xmax() const { return vals[0][1]; }
348  T ymin() const { return vals[1][0]; }
349  T ymax() const { return vals[1][1]; }
350 
351  T xsize() const { return vals[0][1] - vals[0][0]; }
352  T ysize() const { return vals[1][1] - vals[1][0]; }
353 
354  // Intersect a ray with the rect. Returns 0 if no intersection found.
355  // distance will be set to the intersection distance (between 0 & tmax)
356  inline int intersectRay(const UT_Vector2T<T> &orig,
357  const UT_Vector2T<T> &dir,
358  T tmax = 1E17,
359  T *distance = 0,
360  UT_Vector2T<T> *xsect = 0) const;
361 
362  // I/O friends:
363  friend std::ostream &operator<<(std::ostream &os,
364  const UT_BoundingRectT<T> &brect)
365  {
366  brect.save(os);
367  return os;
368  }
369  /// @{
370  /// Methods to serialize to a JSON stream. The vector is stored as an
371  /// array of 4 reals (xmin, xmax, ymin, ymax)
372  UT_API bool save(UT_JSONWriter &w) const;
373  UT_API bool save(UT_JSONValue &v) const;
374  UT_API bool load(UT_JSONParser &p);
375  /// @}
376 
377  UT_API void dump(const char *msg="") const;
378  UT_API void dump(std::ostream &os) const;
379 
380  /// @{
381  /// Access to the serialized data
382  const T *getSerialized() const { return myFloats; }
383  const T *data() const { return myFloats; }
384  T *data() { return myFloats; }
385  /// @}
386 
387  /// @{
388  /// Iterate over the data serially
389  const T *begin() const { return &myFloats[0]; }
390  const T *end() const { return &myFloats[4]; }
391  T *begin() { return &myFloats[0]; }
392  T *end() { return &myFloats[4]; }
393  /// @}
394 
395  /// @{
396  /// Compute a hash
397  uint64 hash() const;
398  friend std::size_t hash_value(const this_type &t) { return t.hash(); }
399  /// @}
400 
401  union {
402  T vals[2][2];
404  };
405 private:
406  UT_API void save(std::ostream &os) const;
407 };
408 
409 template <typename T>
410 UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingRectT<T> &v);
411 
418 
419 #include "UT_BoundingRectImpl.h"
420 
421 #endif
int intersects(const UT_BoundingRectT< T > &rect, T tol) const
T vec[tuple_size]
Definition: UT_Vector2.h:476
#define SYSmax(a, b)
Definition: SYS_Math.h:1570
void stretch(T percent=0.001, T min=0.001)
UT_BoundingRectT(const UT_BoundingRectT< U > &src)
UT_BoundingRectT< fpreal > UT_BoundingRectR
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
UT_BoundingRectT< int64 > UT_BoundingRectI
GLenum GLuint GLsizei bufsize
Definition: glcorearb.h:1818
void initBounds(T xmin, T xmax, T ymin, T ymax)
const GLdouble * v
Definition: glcorearb.h:837
const T * getSerialized() const
bool intersectIfOverlapping(const UT_BoundingRectT< T > &src)
const T * data() const
void scale(T xscale, T yscale)
UT_API bool save(UT_JSONWriter &w) const
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
uint8 cohenSutherland(const UT_BoundingRectT< T > &box) const
#define UT_API
Definition: UT_API.h:14
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLint y
Definition: glcorearb.h:103
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
void enlargeBounds(const UT_BoundingRectT< T > &rect)
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
unsigned long long uint64
Definition: SYS_Types.h:117
2D Vector class.
Definition: UT_Vector2.h:159
float fpreal32
Definition: SYS_Types.h:200
void enlargeBounds(const UT_Vector2T< T > &pt)
double fpreal64
Definition: SYS_Types.h:201
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector2.h:423
unsigned char uint8
Definition: SYS_Types.h:36
int contains(const UT_Vector2T< T > &pt, T tol) const
GLdouble n
Definition: glcorearb.h:2008
UT_BoundingRectT< float > UT_BoundingRect
int contains(T x, T y) const
const T * begin() const
UT_BoundingRectT< fpreal32 > UT_BoundingRectF
void initMaxBounds()
Initialize the box to the largest size.
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
int intersectRay(const UT_Vector2T< T > &orig, const UT_Vector2T< T > &dir, T tmax=1E17, T *distance=0, UT_Vector2T< T > *xsect=0) const
void enlargeBounds(const fpreal32 *v)
bool isValid() const
Check whether the bounding box contains at least one point.
void initBounds(const fpreal64 *v)
UT_API void dump(const char *msg="") const
T & operator()(unsigned m, unsigned n)
int intersects(const UT_BoundingRectT< T > &rect) const
void enlargeBounds(const fpreal64 *v)
void enlargeBounds(T x, T y)
GLint GLenum GLint x
Definition: glcorearb.h:409
int operator==(const UT_BoundingRectT< T > &brect) const
friend std::ostream & operator<<(std::ostream &os, const UT_BoundingRectT< T > &brect)
GLdouble t
Definition: glad.h:2397
void clampX(T min, T max)
void project(T &x, T &y, int *touchx=0, int *touchy=0) const
GLfloat v0
Definition: glcorearb.h:816
void initBounds(const UT_Vector2T< T > &pt)
UT_BoundingRectT(T xmin, T ymin, T xmax, T ymax)
UT_BoundingRectT< int32 > UT_BoundingRecti
UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingRectT< T > &v)
void clampY(T min, T max)
bool operator!=(const UT_BoundingRectT< T > &brect) const
GLfloat GLfloat v1
Definition: glcorearb.h:817
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
int intersects(const UT_Vector2T< T > &v0, const UT_Vector2T< T > &v1, const UT_Vector2T< T > &v2) const
void translate(T x, T y)
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
T operator()(unsigned m, unsigned n) const
UT_Vector2T< T > closestPoint(const UT_Vector2T< T > &pt) const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
friend std::size_t hash_value(const this_type &t)
Compute UT_BoundingRect hash.
uint64 hash() const
Compute UT_BoundingRect hash.
UT_API bool load(UT_JSONParser &p)
void expandBounds(T dx, T dy)
SIM_API const UT_StringHolder distance
const T * end() const
int isInside(const UT_BoundingRectT< T > &brect) const
void enlargeBounds(T xmin, T xmax, T ymin, T ymax)
void initBounds(T x, T y)
int contains(const UT_Vector2T< T > &pt) const
#define SYSmin(a, b)
Definition: SYS_Math.h:1571
UT_BoundingRectT< T > this_type
void intersectBounds(const UT_BoundingRectT< T > &src)
UT_BoundingRectT< fpreal64 > UT_BoundingRectD
void initBounds(const fpreal32 *v)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector2.h:425
void initBounds(const UT_BoundingRectT< T > &rect)
UT_BoundingRectT(const UT_Vector2T< T > &lowerbound, const UT_Vector2T< T > &upperbound)
GLenum src
Definition: glcorearb.h:1793