OpenVDB  0.104.0
Coord.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
31 #ifndef OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
33 
34 #include <openvdb/Platform.h>
35 #include "Math.h"
36 #include "Vec3.h"
37 
38 
39 namespace openvdb {
41 namespace OPENVDB_VERSION_NAME {
42 namespace math {
43 
45 class Coord
46 {
47 public:
48  typedef int32_t Int32;
49  typedef uint32_t Index32;
50  typedef Vec3<Int32> Vec3i;
52 
53  typedef Int32 ValueType;
54  typedef std::numeric_limits<ValueType> Limits;
55 
57  { mVec[0] = mVec[1] = mVec[2] = 0; }
58  explicit Coord(Int32 xyz)
59  { mVec[0] = mVec[1] = mVec[2] = xyz; }
61  { mVec[0] = x; mVec[1] = y; mVec[2] = z; }
63  { mVec[0] = Int32(x); mVec[1] = Int32(y); mVec[2] = Int32(z); }
64  explicit Coord(const Vec3i& v)
65  { mVec[0] = v[0]; mVec[1] = v[1]; mVec[2] = v[2]; }
66  explicit Coord(const Vec3I& v)
67  { mVec[0] = Int32(v[0]); mVec[1] = Int32(v[1]); mVec[2] = Int32(v[2]); }
68  explicit Coord(const Int32* v)
69  { mVec[0] = v[0]; mVec[1] = v[1]; mVec[2] = v[2]; }
70 
71  static const Coord& min() { static const Coord sMin(Limits::min()); return sMin; }
72  static const Coord& max() { static const Coord sMax(Limits::max()); return sMax; }
73 
76  template<typename T> static Coord round(const Vec3<T>& xyz)
77  {
78  return Coord(static_cast<int>(Round(xyz[0])),
79  static_cast<int>(Round(xyz[1])),
80  static_cast<int>(Round(xyz[2])));
81  }
84  template<typename T> static Coord floor(const Vec3<T>& xyz)
85  {
86  return Coord(static_cast<int>(Floor(xyz[0])),
87  static_cast<int>(Floor(xyz[1])),
88  static_cast<int>(Floor(xyz[2])));
89  }
90 
91  Coord& reset(Int32 x, Int32 y, Int32 z)
92  {
93  mVec[0] = x; mVec[1] = y; mVec[2] = z;
94  this->dirty();
95  return *this;
96  }
97  Coord& reset(Index32 x, Index32 y, Index32 z)
98  {
99  return this->reset(Int32(x), Int32(y), Int32(z));
100  }
101  Coord& reset(Int32 xyz) { return this->reset(xyz, xyz, xyz); }
102  Coord& setX(Int32 x) { mVec[0] = x; dirty(); return *this; }
103  Coord& setY(Int32 y) { mVec[1] = y; dirty(); return *this; }
104  Coord& setZ(Int32 z) { mVec[2] = z; dirty(); return *this; }
105  Coord& offset(Int32 dx, Int32 dy, Int32 dz)
106  {
107  mVec[0]+=dx; mVec[1]+=dy; mVec[2]+=dz;
108  this->dirty();
109  return *this;
110  }
111  Coord& offset(Int32 n) { return this->offset(n, n, n); }
112  Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
113  {
114  return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
115  }
116  Coord offsetBy(Int32 n) const { return offsetBy(n, n, n); }
117 
118  Coord& operator+=(const Coord& rhs)
119  {
120  mVec[0] += rhs[0]; mVec[1] += rhs[1]; mVec[2] += rhs[2]; return *this;
121  }
122  Coord& operator-=(const Coord& rhs)
123  {
124  mVec[0] -= rhs[0]; mVec[1] -= rhs[1]; mVec[2] -= rhs[2]; return *this;
125  }
126  Coord operator+(const Coord& rhs) const
127  {
128  return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]);
129  }
130  Coord operator-(const Coord& rhs) const
131  {
132  return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]);
133  }
134  Coord operator-() const { return Coord(-mVec[0], -mVec[1], -mVec[2]); }
135 
136  Coord operator>> (size_t n) const { return Coord(mVec[0]>>n, mVec[1]>>n, mVec[2]>>n); }
137  Coord operator<< (size_t n) const { return Coord(mVec[0]<<n, mVec[1]<<n, mVec[2]<<n); }
138  Coord& operator<<=(size_t n) { mVec[0]<<=n; mVec[1]<<=n; mVec[2]<<=n; dirty(); return *this; }
139  Coord& operator>>=(size_t n) { mVec[0]>>=n; mVec[1]>>=n; mVec[2]>>=n; dirty(); return *this; }
140  Coord operator& (Int32 n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
141  Coord operator| (Int32 n) const { return Coord(mVec[0] | n, mVec[1] | n, mVec[2] | n); }
142  Coord& operator&= (Int32 n) { mVec[0]&=n; mVec[1]&=n; mVec[2]&=n; dirty(); return *this; }
143  Coord& operator|= (Int32 n) { mVec[0]|=n; mVec[1]|=n; mVec[2]|=n; dirty(); return *this; }
144 
145  Int32 x() const { return mVec[0]; }
146  Int32 y() const { return mVec[1]; }
147  Int32 z() const { return mVec[2]; }
148  Int32 operator[](size_t i) const { assert(i < 3); return mVec[i]; }
149  Int32& x() { dirty(); return mVec[0]; }
150  Int32& y() { dirty(); return mVec[1]; }
151  Int32& z() { dirty(); return mVec[2]; }
152  Int32& operator[](size_t i) { assert(i < 3); dirty(); return mVec[i]; }
153 
154  const Int32* asPointer() const { return mVec; }
155  Int32* asPointer() { dirty(); return mVec; }
156  Vec3d asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
157  Vec3s asVec3s() const { return Vec3s(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
158  Vec3i asVec3i() const { return Vec3i(mVec); }
159  Vec3I asVec3I() const
160  {
161  return Vec3I(Index32(mVec[0]), Index32(mVec[1]), Index32(mVec[2]));
162  }
163  void asXYZ(Int32& x, Int32& y, Int32& z) const { x = mVec[0]; y = mVec[1]; z = mVec[2]; }
164 
165  OPENVDB_DEPRECATED void asXYZ(Index32& x, Index32& y, Index32& z) const
166  {
167  x = static_cast<Index32>(mVec[0]);
168  y = static_cast<Index32>(mVec[1]);
169  z = static_cast<Index32>(mVec[2]);
170  }
171 
172  bool operator==(const Coord& rhs) const
173  {
174  return (mVec[0] == rhs.mVec[0] && mVec[1] == rhs.mVec[1] && mVec[2] == rhs.mVec[2]);
175  }
176  bool operator!=(const Coord& rhs) const { return !(*this == rhs); }
177 
179  bool operator<(const Coord& rhs) const
180  {
181  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
182  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
183  : this->z() < rhs.z() ? true : false;
184  }
186  bool operator<=(const Coord& rhs) const
187  {
188  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
189  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
190  : this->z() <=rhs.z() ? true : false;
191  }
193  bool operator>(const Coord& rhs) const { return !(*this <= rhs); }
195  bool operator>=(const Coord& rhs) const { return !(*this < rhs); }
196 
197  //HashType hash() { if (!mHash) { mHash = ...; } return mHash; }
198 
200  void minComponent(const Coord& other)
201  {
202  mVec[0] = std::min(mVec[0], other.mVec[0]);
203  mVec[1] = std::min(mVec[1], other.mVec[1]);
204  mVec[2] = std::min(mVec[2], other.mVec[2]);
205  }
206 
208  void maxComponent(const Coord& other)
209  {
210  mVec[0] = std::max(mVec[0], other.mVec[0]);
211  mVec[1] = std::max(mVec[1], other.mVec[1]);
212  mVec[2] = std::max(mVec[2], other.mVec[2]);
213  }
214 
216  static inline Coord minComponent(const Coord& lhs, const Coord& rhs)
217  {
218  return Coord(std::min(lhs.x(), rhs.x()),
219  std::min(lhs.y(), rhs.y()),
220  std::min(lhs.z(), rhs.z()));
221  }
222 
224  static inline Coord maxComponent(const Coord& lhs, const Coord& rhs)
225  {
226  return Coord(std::max(lhs.x(), rhs.x()),
227  std::max(lhs.y(), rhs.y()),
228  std::max(lhs.z(), rhs.z()));
229  }
230  static inline bool lessThan(const Coord& a, const Coord& b)
231  {
232  return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
233  }
234  void read(std::istream& is) { is.read(reinterpret_cast<char*>(mVec), sizeof(mVec)); }
235  void write(std::ostream& os) const
236  {
237  os.write(reinterpret_cast<const char*>(mVec), sizeof(mVec));
238  }
239 
240  /*
242  static size_t serialSize() { return 3*sizeof(Int32); }
243 
244  inline void serialSave(char*& buffer) const {
245  Index32*& tmp = reinterpret_cast<Int32*&>(buffer);
246  *tmp++ = mVec[0];
247  *tmp++ = mVec[1];
248  *tmp++ = mVec[2];
249  }
250 
251  inline void serialLoad(char*& buffer) {
252  Index32*& tmp = reinterpret_cast<Int32*&>(buffer);
253  mVec[0] = *tmp++;
254  mVec[1] = *tmp++;
255  mVec[2] = *tmp++;
256  }
257  */
258 
259 private:
260  //no-op for now
261  void dirty() { /*mHash.clear();*/ }
262 
263  Int32 mVec[3];
264  //HashType mHash;
265 }; // class Coord
266 
267 
269 
270 
276 {
277 public:
279 
280  // Empty constructor produces an invalid (i.e. empty) bbox!
281  CoordBBox(): mMin(Coord::max()), mMax(Coord::min()) {}
282  // Construct bbox from min and max
283  CoordBBox(const Coord& min, const Coord& max): mMin(min), mMax(max) {}
284  // Construct cube from min and dim
287  mMin(min), mMax(min.offsetBy(dim-1)) {}
288 
289  static CoordBBox createCube(const Coord& min, ValueType dim)
290  {
291  return CoordBBox(min, min.offsetBy(dim - 1));
292  }
293 
295  static const CoordBBox& inf()
296  {
297  static const CoordBBox sInf(Coord::min(), Coord::max());
298  return sInf;
299  }
300 
301  const Coord& min() const { return mMin; }
302  const Coord& max() const { return mMax; }
303 
304  Coord& min() { return mMin; }
305  Coord& max() { return mMax; }
306 
307  void reset(const Coord& min, const Coord& max) { mMin = min; mMax = max; }
308  void resetToCube(const Coord& min, ValueType dim) { mMin = min; mMax = min.offsetBy(dim - 1); }
309  OPENVDB_DEPRECATED void reset(const Coord& min, ValueType dim) { this->resetToCube(min, dim); }
310 
312  Coord getStart() const { return mMin; }
314  Coord getEnd() const { return mMax.offsetBy(1); }
315 
316  bool operator==(const CoordBBox& rhs) const { return mMin == rhs.mMin && mMax == rhs.mMax; }
317  bool operator!=(const CoordBBox& rhs) const { return !(*this == rhs); }
318 
319  bool empty() const { return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]); }
320  operator bool() const { return !this->empty(); }
322  bool hasVolume() const { return !this->empty(); }
326  ValueType volume() const { const Coord d = this->dim(); return d[0] * d[1] * d[2]; }
327 
329  Vec3d getCenter() const { return 0.5 * Vec3d((mMin + mMax).asPointer()); }
330 
334  Coord dim() const { return mMax.offsetBy(1) - mMin; }
336  Coord extents() const { return this->dim(); }
337 
339  size_t maxExtent() const
340  {
341  const Coord d = this->dim();
342  return (d[0] > d[1] && d[0] > d[2]) ? 0 : (d[1] > d[2]) ? 1 : 2;
343  }
344 
346  bool isInside(const Coord& xyz) const
347  {
348  return !(Coord::lessThan(xyz,mMin) || Coord::lessThan(mMax,xyz));
349  }
350 
352  bool isInside(const CoordBBox& b) const
353  {
354  return !(Coord::lessThan(b.mMin,mMin) || Coord::lessThan(mMax,b.mMax));
355  }
356 
358  bool hasOverlap(const CoordBBox& b) const
359  {
360  return !(Coord::lessThan(mMax,b.mMin) || Coord::lessThan(b.mMax,mMin));
361  }
362 
364  void expand(ValueType padding)
365  {
366  mMin.offset(-padding);
367  mMax.offset( padding);
368  }
370  void expand(const Coord& xyz)
371  {
372  mMin.minComponent(xyz);
373  mMax.maxComponent(xyz);
374  }
376  void expand(const CoordBBox& bbox)
377  {
378  mMin.minComponent(bbox.min());
379  mMax.maxComponent(bbox.max());
380  }
381  // Union this bbox with the cubical bbox defined from min and dim
382  void expand(const Coord& min, Coord::ValueType dim)
383  {
384  mMin.minComponent(min);
385  mMax.maxComponent(min.offsetBy(dim-1));
386  }
388  void translate(const Coord& t) { mMin += t; mMax += t; }
389 
391  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
393  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
394 
395 private:
396  Coord mMin, mMax;
397 }; // class CoordBBox
398 
399 
401 
402 
403 inline std::ostream& operator<<(std::ostream& os, const Coord& xyz)
404 {
405  os << xyz.asVec3i(); return os;
406 }
407 
408 
410 
411 template<typename T>
412 inline Vec3<typename promote<T, typename Coord::ValueType>::type>
413 operator+(const Vec3<T>& v0, const Coord& v1)
414 {
416  result[0] += v1[0];
417  result[1] += v1[1];
418  result[2] += v1[2];
419  return result;
420 }
421 
422 template<typename T>
423 inline Vec3<typename promote<T, typename Coord::ValueType>::type>
424 operator+(const Coord& v1, const Vec3<T>& v0)
425 {
427  result[0] += v1[0];
428  result[1] += v1[1];
429  result[2] += v1[2];
430  return result;
431 }
433 
434 
436 
437 template <typename T>
438 inline Vec3<typename promote<T, Coord::ValueType>::type>
439 operator-(const Vec3<T>& v0, const Coord& v1)
440 {
442  result[0] -= v1[0];
443  result[1] -= v1[1];
444  result[2] -= v1[2];
445  return result;
446 }
447 
448 template <typename T>
449 inline Vec3<typename promote<T, Coord::ValueType>::type>
450 operator-(const Coord& v1, const Vec3<T>& v0)
451 {
453  result[0] -= v1[0];
454  result[1] -= v1[1];
455  result[2] -= v1[2];
456  return -result;
457 }
459 
460 inline std::ostream&
461 operator<<(std::ostream& os, const CoordBBox& b)
462 {
463  os << b.min() << " -> " << b.max();
464  return os;
465 }
466 
467 } // namespace math
468 } // namespace OPENVDB_VERSION_NAME
469 } // namespace openvdb
470 
471 #endif // OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
472 
473 // Copyright (c) 2012 DreamWorks Animation LLC
474 // All rights reserved. This software is distributed under the
475 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )