OpenVDB  1.2.0
Coord.h
Go to the documentation of this file.
1 //
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 namespace tbb { class split; } // forward declaration
39 
40 
41 namespace openvdb {
43 namespace OPENVDB_VERSION_NAME {
44 namespace math {
45 
47 class Coord
48 {
49 public:
50  typedef int32_t Int32;
51  typedef uint32_t Index32;
52  typedef Vec3<Int32> Vec3i;
54 
55  typedef Int32 ValueType;
56  typedef std::numeric_limits<ValueType> Limits;
57 
59  { mVec[0] = mVec[1] = mVec[2] = 0; }
60  explicit Coord(Int32 xyz)
61  { mVec[0] = mVec[1] = mVec[2] = xyz; }
63  { mVec[0] = x; mVec[1] = y; mVec[2] = z; }
65  { mVec[0] = Int32(x); mVec[1] = Int32(y); mVec[2] = Int32(z); }
66  explicit Coord(const Vec3i& v)
67  { mVec[0] = v[0]; mVec[1] = v[1]; mVec[2] = v[2]; }
68  explicit Coord(const Vec3I& v)
69  { mVec[0] = Int32(v[0]); mVec[1] = Int32(v[1]); mVec[2] = Int32(v[2]); }
70  explicit Coord(const Int32* v)
71  { mVec[0] = v[0]; mVec[1] = v[1]; mVec[2] = v[2]; }
72 
73  static const Coord& min() { static const Coord sMin(Limits::min()); return sMin; }
74  static const Coord& max() { static const Coord sMax(Limits::max()); return sMax; }
75 
78  template<typename T> static Coord round(const Vec3<T>& xyz)
79  {
80  return Coord(static_cast<int>(Round(xyz[0])),
81  static_cast<int>(Round(xyz[1])),
82  static_cast<int>(Round(xyz[2])));
83  }
86  template<typename T> static Coord floor(const Vec3<T>& xyz)
87  {
88  return Coord(static_cast<int>(Floor(xyz[0])),
89  static_cast<int>(Floor(xyz[1])),
90  static_cast<int>(Floor(xyz[2])));
91  }
92 
95  template<typename T> static Coord ceil(const Vec3<T>& xyz)
96  {
97  return Coord(static_cast<int>(Ceil(xyz[0])),
98  static_cast<int>(Ceil(xyz[1])),
99  static_cast<int>(Ceil(xyz[2])));
100  }
101 
103  {
104  mVec[0] = x; mVec[1] = y; mVec[2] = z;
105  this->dirty();
106  return *this;
107  }
109  {
110  return this->reset(Int32(x), Int32(y), Int32(z));
111  }
112  Coord& reset(Int32 xyz) { return this->reset(xyz, xyz, xyz); }
113  Coord& setX(Int32 x) { mVec[0] = x; dirty(); return *this; }
114  Coord& setY(Int32 y) { mVec[1] = y; dirty(); return *this; }
115  Coord& setZ(Int32 z) { mVec[2] = z; dirty(); return *this; }
116  Coord& offset(Int32 dx, Int32 dy, Int32 dz)
117  {
118  mVec[0]+=dx; mVec[1]+=dy; mVec[2]+=dz;
119  this->dirty();
120  return *this;
121  }
122  Coord& offset(Int32 n) { return this->offset(n, n, n); }
123  Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
124  {
125  return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
126  }
127  Coord offsetBy(Int32 n) const { return offsetBy(n, n, n); }
128 
129  Coord& operator+=(const Coord& rhs)
130  {
131  mVec[0] += rhs[0]; mVec[1] += rhs[1]; mVec[2] += rhs[2]; return *this;
132  }
133  Coord& operator-=(const Coord& rhs)
134  {
135  mVec[0] -= rhs[0]; mVec[1] -= rhs[1]; mVec[2] -= rhs[2]; return *this;
136  }
137  Coord operator+(const Coord& rhs) const
138  {
139  return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]);
140  }
141  Coord operator-(const Coord& rhs) const
142  {
143  return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]);
144  }
145  Coord operator-() const { return Coord(-mVec[0], -mVec[1], -mVec[2]); }
146 
147  Coord operator>> (size_t n) const { return Coord(mVec[0]>>n, mVec[1]>>n, mVec[2]>>n); }
148  Coord operator<< (size_t n) const { return Coord(mVec[0]<<n, mVec[1]<<n, mVec[2]<<n); }
149  Coord& operator<<=(size_t n) { mVec[0]<<=n; mVec[1]<<=n; mVec[2]<<=n; dirty(); return *this; }
150  Coord& operator>>=(size_t n) { mVec[0]>>=n; mVec[1]>>=n; mVec[2]>>=n; dirty(); return *this; }
151  Coord operator& (Int32 n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
152  Coord operator| (Int32 n) const { return Coord(mVec[0] | n, mVec[1] | n, mVec[2] | n); }
153  Coord& operator&= (Int32 n) { mVec[0]&=n; mVec[1]&=n; mVec[2]&=n; dirty(); return *this; }
154  Coord& operator|= (Int32 n) { mVec[0]|=n; mVec[1]|=n; mVec[2]|=n; dirty(); return *this; }
155 
156  Int32 x() const { return mVec[0]; }
157  Int32 y() const { return mVec[1]; }
158  Int32 z() const { return mVec[2]; }
159  Int32 operator[](size_t i) const { assert(i < 3); return mVec[i]; }
160  Int32& x() { dirty(); return mVec[0]; }
161  Int32& y() { dirty(); return mVec[1]; }
162  Int32& z() { dirty(); return mVec[2]; }
163  Int32& operator[](size_t i) { assert(i < 3); dirty(); return mVec[i]; }
164 
165  const Int32* asPointer() const { return mVec; }
166  Int32* asPointer() { dirty(); return mVec; }
167  Vec3d asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
168  Vec3s asVec3s() const { return Vec3s(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
169  Vec3i asVec3i() const { return Vec3i(mVec); }
170  Vec3I asVec3I() const
171  {
172  return Vec3I(Index32(mVec[0]), Index32(mVec[1]), Index32(mVec[2]));
173  }
174  void asXYZ(Int32& x, Int32& y, Int32& z) const { x = mVec[0]; y = mVec[1]; z = mVec[2]; }
175 
176  bool operator==(const Coord& rhs) const
177  {
178  return (mVec[0] == rhs.mVec[0] && mVec[1] == rhs.mVec[1] && mVec[2] == rhs.mVec[2]);
179  }
180  bool operator!=(const Coord& rhs) const { return !(*this == rhs); }
181 
183  bool operator<(const Coord& rhs) const
184  {
185  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
186  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
187  : this->z() < rhs.z() ? true : false;
188  }
190  bool operator<=(const Coord& rhs) const
191  {
192  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
193  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
194  : this->z() <=rhs.z() ? true : false;
195  }
197  bool operator>(const Coord& rhs) const { return !(*this <= rhs); }
199  bool operator>=(const Coord& rhs) const { return !(*this < rhs); }
200 
201  //HashType hash() { if (!mHash) { mHash = ...; } return mHash; }
202 
204  void minComponent(const Coord& other)
205  {
206  mVec[0] = std::min(mVec[0], other.mVec[0]);
207  mVec[1] = std::min(mVec[1], other.mVec[1]);
208  mVec[2] = std::min(mVec[2], other.mVec[2]);
209  }
210 
212  void maxComponent(const Coord& other)
213  {
214  mVec[0] = std::max(mVec[0], other.mVec[0]);
215  mVec[1] = std::max(mVec[1], other.mVec[1]);
216  mVec[2] = std::max(mVec[2], other.mVec[2]);
217  }
218 
220  static inline Coord minComponent(const Coord& lhs, const Coord& rhs)
221  {
222  return Coord(std::min(lhs.x(), rhs.x()),
223  std::min(lhs.y(), rhs.y()),
224  std::min(lhs.z(), rhs.z()));
225  }
226 
228  static inline Coord maxComponent(const Coord& lhs, const Coord& rhs)
229  {
230  return Coord(std::max(lhs.x(), rhs.x()),
231  std::max(lhs.y(), rhs.y()),
232  std::max(lhs.z(), rhs.z()));
233  }
234  static inline bool lessThan(const Coord& a, const Coord& b)
235  {
236  return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
237  }
238 
240  size_t minIndex() const { return MinIndex(mVec); }
241 
243  size_t maxIndex() const { return MaxIndex(mVec); }
244 
245  void read(std::istream& is) { is.read(reinterpret_cast<char*>(mVec), sizeof(mVec)); }
246  void write(std::ostream& os) const
247  {
248  os.write(reinterpret_cast<const char*>(mVec), sizeof(mVec));
249  }
250 
251 private:
252  //no-op for now
253  void dirty() { /*mHash.clear();*/ }
254 
255  Int32 mVec[3];
256  //HashType mHash;
257 }; // class Coord
258 
259 
261 
262 
268 {
269 public:
270  typedef uint64_t Index64;
272 
274  CoordBBox(): mMin(Coord::max()), mMax(Coord::min()) {}
276  CoordBBox(const Coord& min, const Coord& max): mMin(min), mMax(max) {}
279  CoordBBox(CoordBBox& other, const tbb::split&): mMin(other.mMin), mMax(other.mMax)
280  {
281  assert(this->is_divisible());
282  const size_t n = this->maxExtent();
283  mMax[n] = (mMin[n] + mMax[n]) >> 1;
284  other.mMin[n] = mMax[n] + 1;
285  }
286 
287  static CoordBBox createCube(const Coord& min, ValueType dim)
288  {
289  return CoordBBox(min, min.offsetBy(dim - 1));
290  }
291 
293  static CoordBBox inf() { return CoordBBox(Coord::min(), Coord::max()); }
294 
295  const Coord& min() const { return mMin; }
296  const Coord& max() const { return mMax; }
297 
298  Coord& min() { return mMin; }
299  Coord& max() { return mMax; }
300 
301  void reset(const Coord& min, const Coord& max) { mMin = min; mMax = max; }
302  void resetToCube(const Coord& min, ValueType dim) { mMin = min; mMax = min.offsetBy(dim - 1); }
303 
305  Coord getStart() const { return mMin; }
307  Coord getEnd() const { return mMax.offsetBy(1); }
308 
309  bool operator==(const CoordBBox& rhs) const { return mMin == rhs.mMin && mMax == rhs.mMax; }
310  bool operator!=(const CoordBBox& rhs) const { return !(*this == rhs); }
311 
312  bool empty() const { return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]); }
314  operator bool() const { return !this->empty(); }
316  bool hasVolume() const { return !this->empty(); }
318 
320  Vec3d getCenter() const { return 0.5 * Vec3d((mMin + mMax).asPointer()); }
321 
325  Coord dim() const { return mMax.offsetBy(1) - mMin; }
327  Coord extents() const { return this->dim(); }
330  Index64 volume() const
331  {
332  const Coord d = this->dim();
333  return Index64(d[0]) * Index64(d[1]) * Index64(d[2]);
334  }
336  bool is_divisible() const { return mMin[0]<mMax[0] && mMin[1]<mMax[1] && mMin[2]<mMax[2]; }
337 
339  size_t minExtent() const { return this->dim().minIndex(); }
340 
342  size_t maxExtent() const { return this->dim().maxIndex(); }
343 
345  bool isInside(const Coord& xyz) const
346  {
347  return !(Coord::lessThan(xyz,mMin) || Coord::lessThan(mMax,xyz));
348  }
349 
351  bool isInside(const CoordBBox& b) const
352  {
353  return !(Coord::lessThan(b.mMin,mMin) || Coord::lessThan(mMax,b.mMax));
354  }
355 
357  bool hasOverlap(const CoordBBox& b) const
358  {
359  return !(Coord::lessThan(mMax,b.mMin) || Coord::lessThan(b.mMax,mMin));
360  }
361 
363  void expand(ValueType padding)
364  {
365  mMin.offset(-padding);
366  mMax.offset( padding);
367  }
369  void expand(const Coord& xyz)
370  {
371  mMin.minComponent(xyz);
372  mMax.maxComponent(xyz);
373  }
375  void expand(const CoordBBox& bbox)
376  {
377  mMin.minComponent(bbox.min());
378  mMax.maxComponent(bbox.max());
379  }
381  void intersect(const CoordBBox& bbox)
382  {
383  mMin.maxComponent(bbox.min());
384  mMax.minComponent(bbox.max());
385  }
388  void expand(const Coord& min, Coord::ValueType dim)
389  {
390  mMin.minComponent(min);
391  mMax.maxComponent(min.offsetBy(dim-1));
392  }
394  void translate(const Coord& t) { mMin += t; mMax += t; }
395 
397  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
399  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
400 
401 private:
402 
403  Coord mMin, mMax;
404 }; // class CoordBBox
405 
406 
408 
409 
410 inline std::ostream& operator<<(std::ostream& os, const Coord& xyz)
411 {
412  os << xyz.asVec3i(); return os;
413 }
414 
415 
417 template<typename T>
419 inline Vec3<typename promote<T, typename Coord::ValueType>::type>
420 operator+(const Vec3<T>& v0, const Coord& v1)
421 {
423  result[0] += v1[0];
424  result[1] += v1[1];
425  result[2] += v1[2];
426  return result;
427 }
428 
429 template<typename T>
430 inline Vec3<typename promote<T, typename Coord::ValueType>::type>
431 operator+(const Coord& v1, const Vec3<T>& v0)
432 {
434  result[0] += v1[0];
435  result[1] += v1[1];
436  result[2] += v1[2];
437  return result;
438 }
440 
441 
443 template <typename T>
445 inline Vec3<typename promote<T, Coord::ValueType>::type>
446 operator-(const Vec3<T>& v0, const Coord& v1)
447 {
449  result[0] -= v1[0];
450  result[1] -= v1[1];
451  result[2] -= v1[2];
452  return result;
453 }
454 
455 template <typename T>
456 inline Vec3<typename promote<T, Coord::ValueType>::type>
457 operator-(const Coord& v1, const Vec3<T>& v0)
458 {
460  result[0] -= v1[0];
461  result[1] -= v1[1];
462  result[2] -= v1[2];
463  return -result;
464 }
466 
467 inline std::ostream&
468 operator<<(std::ostream& os, const CoordBBox& b)
469 {
470  os << b.min() << " -> " << b.max();
471  return os;
472 }
473 
474 } // namespace math
475 } // namespace OPENVDB_VERSION_NAME
476 } // namespace openvdb
477 
478 #endif // OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
479 
480 // Copyright (c) 2012-2013 DreamWorks Animation LLC
481 // All rights reserved. This software is distributed under the
482 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )