OpenVDB  1.1.0
Coord.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012-2013 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 
93  template<typename T> static Coord ceil(const Vec3<T>& xyz)
94  {
95  return Coord(static_cast<int>(Ceil(xyz[0])),
96  static_cast<int>(Ceil(xyz[1])),
97  static_cast<int>(Ceil(xyz[2])));
98  }
99 
100  Coord& reset(Int32 x, Int32 y, Int32 z)
101  {
102  mVec[0] = x; mVec[1] = y; mVec[2] = z;
103  this->dirty();
104  return *this;
105  }
106  Coord& reset(Index32 x, Index32 y, Index32 z)
107  {
108  return this->reset(Int32(x), Int32(y), Int32(z));
109  }
110  Coord& reset(Int32 xyz) { return this->reset(xyz, xyz, xyz); }
111  Coord& setX(Int32 x) { mVec[0] = x; dirty(); return *this; }
112  Coord& setY(Int32 y) { mVec[1] = y; dirty(); return *this; }
113  Coord& setZ(Int32 z) { mVec[2] = z; dirty(); return *this; }
114  Coord& offset(Int32 dx, Int32 dy, Int32 dz)
115  {
116  mVec[0]+=dx; mVec[1]+=dy; mVec[2]+=dz;
117  this->dirty();
118  return *this;
119  }
120  Coord& offset(Int32 n) { return this->offset(n, n, n); }
121  Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
122  {
123  return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
124  }
125  Coord offsetBy(Int32 n) const { return offsetBy(n, n, n); }
126 
127  Coord& operator+=(const Coord& rhs)
128  {
129  mVec[0] += rhs[0]; mVec[1] += rhs[1]; mVec[2] += rhs[2]; return *this;
130  }
131  Coord& operator-=(const Coord& rhs)
132  {
133  mVec[0] -= rhs[0]; mVec[1] -= rhs[1]; mVec[2] -= rhs[2]; return *this;
134  }
135  Coord operator+(const Coord& rhs) const
136  {
137  return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]);
138  }
139  Coord operator-(const Coord& rhs) const
140  {
141  return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]);
142  }
143  Coord operator-() const { return Coord(-mVec[0], -mVec[1], -mVec[2]); }
144 
145  Coord operator>> (size_t n) const { return Coord(mVec[0]>>n, mVec[1]>>n, mVec[2]>>n); }
146  Coord operator<< (size_t n) const { return Coord(mVec[0]<<n, mVec[1]<<n, mVec[2]<<n); }
147  Coord& operator<<=(size_t n) { mVec[0]<<=n; mVec[1]<<=n; mVec[2]<<=n; dirty(); return *this; }
148  Coord& operator>>=(size_t n) { mVec[0]>>=n; mVec[1]>>=n; mVec[2]>>=n; dirty(); return *this; }
149  Coord operator& (Int32 n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
150  Coord operator| (Int32 n) const { return Coord(mVec[0] | n, mVec[1] | n, mVec[2] | n); }
151  Coord& operator&= (Int32 n) { mVec[0]&=n; mVec[1]&=n; mVec[2]&=n; dirty(); return *this; }
152  Coord& operator|= (Int32 n) { mVec[0]|=n; mVec[1]|=n; mVec[2]|=n; dirty(); return *this; }
153 
154  Int32 x() const { return mVec[0]; }
155  Int32 y() const { return mVec[1]; }
156  Int32 z() const { return mVec[2]; }
157  Int32 operator[](size_t i) const { assert(i < 3); return mVec[i]; }
158  Int32& x() { dirty(); return mVec[0]; }
159  Int32& y() { dirty(); return mVec[1]; }
160  Int32& z() { dirty(); return mVec[2]; }
161  Int32& operator[](size_t i) { assert(i < 3); dirty(); return mVec[i]; }
162 
163  const Int32* asPointer() const { return mVec; }
164  Int32* asPointer() { dirty(); return mVec; }
165  Vec3d asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
166  Vec3s asVec3s() const { return Vec3s(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
167  Vec3i asVec3i() const { return Vec3i(mVec); }
168  Vec3I asVec3I() const
169  {
170  return Vec3I(Index32(mVec[0]), Index32(mVec[1]), Index32(mVec[2]));
171  }
172  void asXYZ(Int32& x, Int32& y, Int32& z) const { x = mVec[0]; y = mVec[1]; z = mVec[2]; }
173 
174  bool operator==(const Coord& rhs) const
175  {
176  return (mVec[0] == rhs.mVec[0] && mVec[1] == rhs.mVec[1] && mVec[2] == rhs.mVec[2]);
177  }
178  bool operator!=(const Coord& rhs) const { return !(*this == rhs); }
179 
181  bool operator<(const Coord& rhs) const
182  {
183  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
184  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
185  : this->z() < rhs.z() ? true : false;
186  }
188  bool operator<=(const Coord& rhs) const
189  {
190  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
191  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
192  : this->z() <=rhs.z() ? true : false;
193  }
195  bool operator>(const Coord& rhs) const { return !(*this <= rhs); }
197  bool operator>=(const Coord& rhs) const { return !(*this < rhs); }
198 
199  //HashType hash() { if (!mHash) { mHash = ...; } return mHash; }
200 
202  void minComponent(const Coord& other)
203  {
204  mVec[0] = std::min(mVec[0], other.mVec[0]);
205  mVec[1] = std::min(mVec[1], other.mVec[1]);
206  mVec[2] = std::min(mVec[2], other.mVec[2]);
207  }
208 
210  void maxComponent(const Coord& other)
211  {
212  mVec[0] = std::max(mVec[0], other.mVec[0]);
213  mVec[1] = std::max(mVec[1], other.mVec[1]);
214  mVec[2] = std::max(mVec[2], other.mVec[2]);
215  }
216 
218  static inline Coord minComponent(const Coord& lhs, const Coord& rhs)
219  {
220  return Coord(std::min(lhs.x(), rhs.x()),
221  std::min(lhs.y(), rhs.y()),
222  std::min(lhs.z(), rhs.z()));
223  }
224 
226  static inline Coord maxComponent(const Coord& lhs, const Coord& rhs)
227  {
228  return Coord(std::max(lhs.x(), rhs.x()),
229  std::max(lhs.y(), rhs.y()),
230  std::max(lhs.z(), rhs.z()));
231  }
232  static inline bool lessThan(const Coord& a, const Coord& b)
233  {
234  return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
235  }
236  void read(std::istream& is) { is.read(reinterpret_cast<char*>(mVec), sizeof(mVec)); }
237  void write(std::ostream& os) const
238  {
239  os.write(reinterpret_cast<const char*>(mVec), sizeof(mVec));
240  }
241 
242 private:
243  //no-op for now
244  void dirty() { /*mHash.clear();*/ }
245 
246  Int32 mVec[3];
247  //HashType mHash;
248 }; // class Coord
249 
250 
252 
253 
259 {
260 public:
262 
263  // Empty constructor produces an invalid (i.e. empty) bbox!
264  CoordBBox(): mMin(Coord::max()), mMax(Coord::min()) {}
265  // Construct bbox from min and max
266  CoordBBox(const Coord& min, const Coord& max): mMin(min), mMax(max) {}
267 
268  static CoordBBox createCube(const Coord& min, ValueType dim)
269  {
270  return CoordBBox(min, min.offsetBy(dim - 1));
271  }
272 
274  static const CoordBBox& inf()
275  {
276  static const CoordBBox sInf(Coord::min(), Coord::max());
277  return sInf;
278  }
279 
280  const Coord& min() const { return mMin; }
281  const Coord& max() const { return mMax; }
282 
283  Coord& min() { return mMin; }
284  Coord& max() { return mMax; }
285 
286  void reset(const Coord& min, const Coord& max) { mMin = min; mMax = max; }
287  void resetToCube(const Coord& min, ValueType dim) { mMin = min; mMax = min.offsetBy(dim - 1); }
288 
290  Coord getStart() const { return mMin; }
292  Coord getEnd() const { return mMax.offsetBy(1); }
293 
294  bool operator==(const CoordBBox& rhs) const { return mMin == rhs.mMin && mMax == rhs.mMax; }
295  bool operator!=(const CoordBBox& rhs) const { return !(*this == rhs); }
296 
297  bool empty() const { return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]); }
298  operator bool() const { return !this->empty(); }
300  bool hasVolume() const { return !this->empty(); }
304  ValueType volume() const { const Coord d = this->dim(); return d[0] * d[1] * d[2]; }
305 
307  Vec3d getCenter() const { return 0.5 * Vec3d((mMin + mMax).asPointer()); }
308 
312  Coord dim() const { return mMax.offsetBy(1) - mMin; }
314  Coord extents() const { return this->dim(); }
315 
317  size_t maxExtent() const
318  {
319  const Coord d = this->dim();
320  return (d[0] > d[1] && d[0] > d[2]) ? 0 : (d[1] > d[2]) ? 1 : 2;
321  }
322 
324  bool isInside(const Coord& xyz) const
325  {
326  return !(Coord::lessThan(xyz,mMin) || Coord::lessThan(mMax,xyz));
327  }
328 
330  bool isInside(const CoordBBox& b) const
331  {
332  return !(Coord::lessThan(b.mMin,mMin) || Coord::lessThan(mMax,b.mMax));
333  }
334 
336  bool hasOverlap(const CoordBBox& b) const
337  {
338  return !(Coord::lessThan(mMax,b.mMin) || Coord::lessThan(b.mMax,mMin));
339  }
340 
342  void expand(ValueType padding)
343  {
344  mMin.offset(-padding);
345  mMax.offset( padding);
346  }
348  void expand(const Coord& xyz)
349  {
350  mMin.minComponent(xyz);
351  mMax.maxComponent(xyz);
352  }
354  void expand(const CoordBBox& bbox)
355  {
356  mMin.minComponent(bbox.min());
357  mMax.maxComponent(bbox.max());
358  }
359  // Union this bbox with the cubical bbox defined from min and dim
360  void expand(const Coord& min, Coord::ValueType dim)
361  {
362  mMin.minComponent(min);
363  mMax.maxComponent(min.offsetBy(dim-1));
364  }
366  void translate(const Coord& t) { mMin += t; mMax += t; }
367 
369  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
371  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
372 
373 private:
374  Coord mMin, mMax;
375 }; // class CoordBBox
376 
377 
379 
380 
381 inline std::ostream& operator<<(std::ostream& os, const Coord& xyz)
382 {
383  os << xyz.asVec3i(); return os;
384 }
385 
386 
388 
389 template<typename T>
390 inline Vec3<typename promote<T, typename Coord::ValueType>::type>
391 operator+(const Vec3<T>& v0, const Coord& v1)
392 {
394  result[0] += v1[0];
395  result[1] += v1[1];
396  result[2] += v1[2];
397  return result;
398 }
399 
400 template<typename T>
401 inline Vec3<typename promote<T, typename Coord::ValueType>::type>
402 operator+(const Coord& v1, const Vec3<T>& v0)
403 {
405  result[0] += v1[0];
406  result[1] += v1[1];
407  result[2] += v1[2];
408  return result;
409 }
411 
412 
414 
415 template <typename T>
416 inline Vec3<typename promote<T, Coord::ValueType>::type>
417 operator-(const Vec3<T>& v0, const Coord& v1)
418 {
420  result[0] -= v1[0];
421  result[1] -= v1[1];
422  result[2] -= v1[2];
423  return result;
424 }
425 
426 template <typename T>
427 inline Vec3<typename promote<T, Coord::ValueType>::type>
428 operator-(const Coord& v1, const Vec3<T>& v0)
429 {
431  result[0] -= v1[0];
432  result[1] -= v1[1];
433  result[2] -= v1[2];
434  return -result;
435 }
437 
438 inline std::ostream&
439 operator<<(std::ostream& os, const CoordBBox& b)
440 {
441  os << b.min() << " -> " << b.max();
442  return os;
443 }
444 
445 } // namespace math
446 } // namespace OPENVDB_VERSION_NAME
447 } // namespace openvdb
448 
449 #endif // OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
450 
451 // Copyright (c) 2012-2013 DreamWorks Animation LLC
452 // All rights reserved. This software is distributed under the
453 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )