OpenVDB  3.1.0
Maps.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2015 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 //
32 
33 #ifndef OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
34 #define OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
35 
36 #include "Math.h"
37 #include "Mat4.h"
38 #include "Vec3.h"
39 #include "BBox.h"
40 #include "Coord.h"
41 #include <openvdb/io/io.h> // for io::getFormatVersion()
42 #include <openvdb/util/Name.h>
43 #include <openvdb/Types.h>
44 #include <boost/shared_ptr.hpp>
45 #include <map>
46 
47 namespace openvdb {
49 namespace OPENVDB_VERSION_NAME {
50 namespace math {
51 
52 
54 
56 
57 class MapBase;
58 class ScaleMap;
59 class TranslationMap;
60 class ScaleTranslateMap;
61 class UniformScaleMap;
62 class UniformScaleTranslateMap;
63 class AffineMap;
64 class UnitaryMap;
65 class NonlinearFrustumMap;
66 
67 template<typename T1, typename T2> class CompoundMap;
68 
71 typedef SpectralDecomposedMap SymmetricMap;
74 
75 
77 
79 
80 template<typename T> struct is_linear { static const bool value = false; };
81 template<> struct is_linear<AffineMap> { static const bool value = true; };
82 template<> struct is_linear<ScaleMap> { static const bool value = true; };
83 template<> struct is_linear<UniformScaleMap> { static const bool value = true; };
84 template<> struct is_linear<UnitaryMap> { static const bool value = true; };
85 template<> struct is_linear<TranslationMap> { static const bool value = true; };
86 template<> struct is_linear<ScaleTranslateMap> { static const bool value = true; };
87 template<> struct is_linear<UniformScaleTranslateMap> { static const bool value = true; };
88 
89 template<typename T1, typename T2> struct is_linear<CompoundMap<T1, T2> > {
90  static const bool value = is_linear<T1>::value && is_linear<T2>::value;
91 };
92 
93 
94 template<typename T> struct is_uniform_scale { static const bool value = false; };
95 template<> struct is_uniform_scale<UniformScaleMap> { static const bool value = true; };
96 
97 template<typename T> struct is_uniform_scale_translate { static const bool value = false; };
98 template<> struct is_uniform_scale_translate<TranslationMap> { static const bool value = true; };
100  static const bool value = true;
101 };
102 
103 
104 template<typename T> struct is_scale { static const bool value = false; };
105 template<> struct is_scale<ScaleMap> { static const bool value = true; };
106 
107 template<typename T> struct is_scale_translate { static const bool value = false; };
108 template<> struct is_scale_translate<ScaleTranslateMap> { static const bool value = true; };
109 
110 
111 template<typename T> struct is_uniform_diagonal_jacobian {
113 };
114 
115 template<typename T> struct is_diagonal_jacobian {
116  static const bool value = is_scale<T>::value || is_scale_translate<T>::value;
117 };
118 
119 
121 
123 
126 OPENVDB_API boost::shared_ptr<SymmetricMap> createSymmetricMap(const Mat3d& m);
127 
128 
131 OPENVDB_API boost::shared_ptr<FullyDecomposedMap> createFullyDecomposedMap(const Mat4d& m);
132 
133 
144 OPENVDB_API boost::shared_ptr<PolarDecomposedMap> createPolarDecomposedMap(const Mat3d& m);
145 
146 
148 OPENVDB_API boost::shared_ptr<MapBase> simplify(boost::shared_ptr<AffineMap> affine);
149 
153 
154 
156 
157 
160 {
161 public:
162  typedef boost::shared_ptr<MapBase> Ptr;
163  typedef boost::shared_ptr<const MapBase> ConstPtr;
164  typedef Ptr (*MapFactory)();
165 
166  virtual ~MapBase(){}
167 
168  virtual boost::shared_ptr<AffineMap> getAffineMap() const = 0;
169 
171  virtual Name type() const = 0;
172 
174  template<typename MapT> bool isType() const { return this->type() == MapT::mapType(); }
175 
177  virtual bool isEqual(const MapBase& other) const = 0;
178 
180  virtual bool isLinear() const = 0;
182  virtual bool hasUniformScale() const = 0;
183 
184  virtual Vec3d applyMap(const Vec3d& in) const = 0;
185  virtual Vec3d applyInverseMap(const Vec3d& in) const = 0;
186 
188  virtual Vec3d applyIJT(const Vec3d& in) const = 0;
192  virtual Vec3d applyIJT(const Vec3d& in, const Vec3d& domainPos) const = 0;
194 
195  virtual Mat3d applyIJC(const Mat3d& m) const = 0;
196  virtual Mat3d applyIJC(const Mat3d& m, const Vec3d& v, const Vec3d& domainPos) const = 0;
197 
198 
199  virtual double determinant() const = 0;
200  virtual double determinant(const Vec3d&) const = 0;
201 
202 
204  virtual Vec3d voxelSize() const = 0;
208  virtual Vec3d voxelSize(const Vec3d&) const = 0;
210 
211  virtual void read(std::istream&) = 0;
212  virtual void write(std::ostream&) const = 0;
213 
214  virtual std::string str() const = 0;
215 
216  virtual MapBase::Ptr copy() const = 0;
217 
219  virtual MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const = 0;
221  virtual MapBase::Ptr preTranslate(const Vec3d&) const = 0;
222  virtual MapBase::Ptr preScale(const Vec3d&) const = 0;
223  virtual MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const = 0;
224 
225  virtual MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const = 0;
226  virtual MapBase::Ptr postTranslate(const Vec3d&) const = 0;
227  virtual MapBase::Ptr postScale(const Vec3d&) const = 0;
228  virtual MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const = 0;
230 
232  virtual Vec3d applyJacobian(const Vec3d& in) const = 0;
238  virtual Vec3d applyJacobian(const Vec3d& in, const Vec3d& domainPos) const = 0;
240 
242  virtual Vec3d applyInverseJacobian(const Vec3d& in) const = 0;
248  virtual Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d& domainPos) const = 0;
250 
251 
253  virtual Vec3d applyJT(const Vec3d& in) const = 0;
260  virtual Vec3d applyJT(const Vec3d& in, const Vec3d& domainPos) const = 0;
262 
268  virtual MapBase::Ptr inverseMap() const = 0;
269 
270 protected:
271  MapBase() {}
272 
273  template<typename MapT>
274  static bool isEqualBase(const MapT& self, const MapBase& other)
275  {
276  return other.isType<MapT>() && (self == *static_cast<const MapT*>(&other));
277  }
278 };
279 
280 
282 
283 
287 {
288 public:
289  typedef std::map<Name, MapBase::MapFactory> MapDictionary;
290 
291  static MapRegistry* instance();
292 
294  static MapBase::Ptr createMap(const Name&);
295 
297  static bool isRegistered(const Name&);
298 
300  static void registerMap(const Name&, MapBase::MapFactory);
301 
303  static void unregisterMap(const Name&);
304 
306  static void clear();
307 
308 private:
309  MapRegistry() {}
310 
311  static MapRegistry* staticInstance();
312 
313  static MapRegistry* mInstance;
314 
315  MapDictionary mMap;
316 };
317 
318 
320 
321 
325 {
326 public:
327  typedef boost::shared_ptr<AffineMap> Ptr;
328  typedef boost::shared_ptr<const AffineMap> ConstPtr;
329 
331  mMatrix(Mat4d::identity()),
332  mMatrixInv(Mat4d::identity()),
333  mJacobianInv(Mat3d::identity()),
334  mDeterminant(1),
335  mVoxelSize(Vec3d(1,1,1)),
336  mIsDiagonal(true),
337  mIsIdentity(true)
338  // the default constructor for translation is zero
339  {
340  }
341 
342  AffineMap(const Mat3d& m)
343  {
344  Mat4d mat4(Mat4d::identity());
345  mat4.setMat3(m);
346  mMatrix = mat4;
347  updateAcceleration();
348  }
349 
350  AffineMap(const Mat4d& m): mMatrix(m)
351  {
352  if (!isAffine(m)) {
354  "Tried to initialize an affine transform from a non-affine 4x4 matrix");
355  }
356  updateAcceleration();
357  }
358 
359  AffineMap(const AffineMap& other):
360  MapBase(other),
361  mMatrix(other.mMatrix),
362  mMatrixInv(other.mMatrixInv),
363  mJacobianInv(other.mJacobianInv),
364  mDeterminant(other.mDeterminant),
365  mVoxelSize(other.mVoxelSize),
366  mIsDiagonal(other.mIsDiagonal),
367  mIsIdentity(other.mIsIdentity)
368  {
369  }
370 
372  AffineMap(const AffineMap& first, const AffineMap& second):
373  mMatrix(first.mMatrix * second.mMatrix)
374  {
375  updateAcceleration();
376  }
377 
379 
381  static MapBase::Ptr create() { return MapBase::Ptr(new AffineMap()); }
383  MapBase::Ptr copy() const { return MapBase::Ptr(new AffineMap(*this)); }
384 
385  MapBase::Ptr inverseMap() const { return MapBase::Ptr(new AffineMap(mMatrixInv)); }
386 
387  static bool isRegistered() { return MapRegistry::isRegistered(AffineMap::mapType()); }
388 
389  static void registerMap()
390  {
391  MapRegistry::registerMap(
392  AffineMap::mapType(),
393  AffineMap::create);
394  }
395 
396  Name type() const { return mapType(); }
397  static Name mapType() { return Name("AffineMap"); }
398 
400  bool isLinear() const { return true; }
401 
403  bool hasUniformScale() const
404  {
405  Mat3d mat = mMatrix.getMat3();
406  const double det = mat.det();
407  if (isApproxEqual(det, double(0))) {
408  return false;
409  } else {
410  mat *= (1.f / pow(std::abs(det),1./3.));
411  return isUnitary(mat);
412  }
413  }
414 
415  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
416 
417  bool operator==(const AffineMap& other) const
418  {
419  // the Mat.eq() is approximate
420  if (!mMatrix.eq(other.mMatrix)) { return false; }
421  if (!mMatrixInv.eq(other.mMatrixInv)) { return false; }
422  return true;
423  }
424 
425  bool operator!=(const AffineMap& other) const { return !(*this == other); }
426 
428  {
429  mMatrix = other.mMatrix;
430  mMatrixInv = other.mMatrixInv;
431 
432  mJacobianInv = other.mJacobianInv;
433  mDeterminant = other.mDeterminant;
434  mVoxelSize = other.mVoxelSize;
435  mIsDiagonal = other.mIsDiagonal;
436  mIsIdentity = other.mIsIdentity;
437  return *this;
438  }
440  Vec3d applyMap(const Vec3d& in) const { return in * mMatrix; }
442  Vec3d applyInverseMap(const Vec3d& in) const {return in * mMatrixInv; }
443 
445  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
447  Vec3d applyJacobian(const Vec3d& in) const { return mMatrix.transform3x3(in); }
448 
450  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
452  Vec3d applyInverseJacobian(const Vec3d& in) const { return mMatrixInv.transform3x3(in); }
453 
456  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
458  Vec3d applyJT(const Vec3d& in) const {
459  const double* m = mMatrix.asPointer();
460  return Vec3d( m[ 0] * in[0] + m[ 1] * in[1] + m[ 2] * in[2],
461  m[ 4] * in[0] + m[ 5] * in[1] + m[ 6] * in[2],
462  m[ 8] * in[0] + m[ 9] * in[1] + m[10] * in[2] );
463  }
464 
466  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const { return applyIJT(in); }
468  Vec3d applyIJT(const Vec3d& in) const { return in * mJacobianInv; }
470  Mat3d applyIJC(const Mat3d& m) const {
471  return mJacobianInv.transpose()* m * mJacobianInv;
472  }
473  Mat3d applyIJC(const Mat3d& in, const Vec3d& , const Vec3d& ) const {
474  return applyIJC(in);
475  }
477  double determinant(const Vec3d& ) const { return determinant(); }
479  double determinant() const { return mDeterminant; }
480 
482  Vec3d voxelSize() const { return mVoxelSize; }
485  Vec3d voxelSize(const Vec3d&) const { return voxelSize(); }
487 
489  bool isIdentity() const { return mIsIdentity; }
491  bool isDiagonal() const { return mIsDiagonal; }
493  bool isScale() const { return isDiagonal(); }
495  bool isScaleTranslate() const { return math::isDiagonal(mMatrix.getMat3()); }
496 
497 
498  // Methods that modify the existing affine map
499 
501  void accumPreRotation(Axis axis, double radians)
503  {
504  mMatrix.preRotate(axis, radians);
505  updateAcceleration();
506  }
507  void accumPreScale(const Vec3d& v)
508  {
509  mMatrix.preScale(v);
510  updateAcceleration();
511  }
512  void accumPreTranslation(const Vec3d& v)
513  {
514  mMatrix.preTranslate(v);
515  updateAcceleration();
516  }
517  void accumPreShear(Axis axis0, Axis axis1, double shear)
518  {
519  mMatrix.preShear(axis0, axis1, shear);
520  updateAcceleration();
521  }
523 
524 
526  void accumPostRotation(Axis axis, double radians)
528  {
529  mMatrix.postRotate(axis, radians);
530  updateAcceleration();
531  }
532  void accumPostScale(const Vec3d& v)
533  {
534  mMatrix.postScale(v);
535  updateAcceleration();
536  }
538  {
539  mMatrix.postTranslate(v);
540  updateAcceleration();
541  }
542  void accumPostShear(Axis axis0, Axis axis1, double shear)
543  {
544  mMatrix.postShear(axis0, axis1, shear);
545  updateAcceleration();
546  }
548 
549 
551  void read(std::istream& is)
552  {
553  mMatrix.read(is);
554  updateAcceleration();
555  }
556 
558  void write(std::ostream& os) const
559  {
560  mMatrix.write(os);
561  }
562 
564  std::string str() const
565  {
566  std::ostringstream buffer;
567  buffer << " - mat4:\n" << mMatrix.str() << std::endl;
568  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
569  return buffer.str();
570  }
571 
573  boost::shared_ptr<FullyDecomposedMap> createDecomposedMap()
574  {
575  return createFullyDecomposedMap(mMatrix);
576  }
577 
579  AffineMap::Ptr getAffineMap() const { return AffineMap::Ptr(new AffineMap(*this)); }
580 
582  AffineMap::Ptr inverse() const { return AffineMap::Ptr(new AffineMap(mMatrixInv)); }
583 
584 
586  MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const
589  {
590  AffineMap::Ptr affineMap = getAffineMap();
591  affineMap->accumPreRotation(axis, radians);
592  return simplify(affineMap);
593  }
595  {
596  AffineMap::Ptr affineMap = getAffineMap();
597  affineMap->accumPreTranslation(t);
598  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
599  }
600  MapBase::Ptr preScale(const Vec3d& s) const
601  {
602  AffineMap::Ptr affineMap = getAffineMap();
603  affineMap->accumPreScale(s);
604  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
605  }
606  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
607  {
608  AffineMap::Ptr affineMap = getAffineMap();
609  affineMap->accumPreShear(axis0, axis1, shear);
610  return simplify(affineMap);
611  }
613 
614 
616  MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const
619  {
620  AffineMap::Ptr affineMap = getAffineMap();
621  affineMap->accumPostRotation(axis, radians);
622  return simplify(affineMap);
623  }
625  {
626  AffineMap::Ptr affineMap = getAffineMap();
627  affineMap->accumPostTranslation(t);
628  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
629  }
630  MapBase::Ptr postScale(const Vec3d& s) const
631  {
632  AffineMap::Ptr affineMap = getAffineMap();
633  affineMap->accumPostScale(s);
634  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
635  }
636  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
637  {
638  AffineMap::Ptr affineMap = getAffineMap();
639  affineMap->accumPostShear(axis0, axis1, shear);
640  return simplify(affineMap);
641  }
643 
645  Mat4d getMat4() const { return mMatrix;}
646  const Mat4d& getConstMat4() const {return mMatrix;}
647  const Mat3d& getConstJacobianInv() const {return mJacobianInv;}
648 
649 private:
650  void updateAcceleration() {
651  Mat3d mat3 = mMatrix.getMat3();
652  mDeterminant = mat3.det();
653 
654  if (std::abs(mDeterminant) < (3.0 * math::Tolerance<double>::value())) {
656  "Tried to initialize an affine transform from a nearly singular matrix");
657  }
658  mMatrixInv = mMatrix.inverse();
659  mJacobianInv = mat3.inverse().transpose();
660  mIsDiagonal = math::isDiagonal(mMatrix);
661  mIsIdentity = math::isIdentity(mMatrix);
662  Vec3d pos = applyMap(Vec3d(0,0,0));
663  mVoxelSize(0) = (applyMap(Vec3d(1,0,0)) - pos).length();
664  mVoxelSize(1) = (applyMap(Vec3d(0,1,0)) - pos).length();
665  mVoxelSize(2) = (applyMap(Vec3d(0,0,1)) - pos).length();
666  }
667 
668  // the underlying matrix
669  Mat4d mMatrix;
670 
671  // stored for acceleration
672  Mat4d mMatrixInv;
673  Mat3d mJacobianInv;
674  double mDeterminant;
675  Vec3d mVoxelSize;
676  bool mIsDiagonal, mIsIdentity;
677 }; // class AffineMap
678 
679 
681 
682 
686 {
687 public:
688  typedef boost::shared_ptr<ScaleMap> Ptr;
689  typedef boost::shared_ptr<const ScaleMap> ConstPtr;
690 
691  ScaleMap(): MapBase(), mScaleValues(Vec3d(1,1,1)), mVoxelSize(Vec3d(1,1,1)),
692  mScaleValuesInverse(Vec3d(1,1,1)),
693  mInvScaleSqr(1,1,1), mInvTwiceScale(0.5,0.5,0.5){}
694 
696  MapBase(),
697  mScaleValues(scale),
698  mVoxelSize(Vec3d(std::abs(scale(0)),std::abs(scale(1)), std::abs(scale(2))))
699  {
700  double determinant = scale[0]* scale[1] * scale[2];
701  if (std::abs(determinant) < 3.0 * math::Tolerance<double>::value()) {
702  OPENVDB_THROW(ArithmeticError, "Non-zero scale values required");
703  }
704  mScaleValuesInverse = 1.0 / mScaleValues;
705  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
706  mInvTwiceScale = mScaleValuesInverse / 2;
707  }
708 
709  ScaleMap(const ScaleMap& other):
710  MapBase(),
711  mScaleValues(other.mScaleValues),
712  mVoxelSize(other.mVoxelSize),
713  mScaleValuesInverse(other.mScaleValuesInverse),
714  mInvScaleSqr(other.mInvScaleSqr),
715  mInvTwiceScale(other.mInvTwiceScale)
716  {
717  }
718 
720 
722  static MapBase::Ptr create() { return MapBase::Ptr(new ScaleMap()); }
724  MapBase::Ptr copy() const { return MapBase::Ptr(new ScaleMap(*this)); }
725 
726  MapBase::Ptr inverseMap() const { return MapBase::Ptr(new ScaleMap(mScaleValuesInverse)); }
727 
728  static bool isRegistered() { return MapRegistry::isRegistered(ScaleMap::mapType()); }
729 
730  static void registerMap()
731  {
732  MapRegistry::registerMap(
733  ScaleMap::mapType(),
734  ScaleMap::create);
735  }
736 
737  Name type() const { return mapType(); }
738  static Name mapType() { return Name("ScaleMap"); }
739 
741  bool isLinear() const { return true; }
742 
744  bool hasUniformScale() const
745  {
746  bool value = isApproxEqual(
747  std::abs(mScaleValues.x()), std::abs(mScaleValues.y()), double(5e-7));
748  value = value && isApproxEqual(
749  std::abs(mScaleValues.x()), std::abs(mScaleValues.z()), double(5e-7));
750  return value;
751  }
752 
754  Vec3d applyMap(const Vec3d& in) const
755  {
756  return Vec3d(
757  in.x() * mScaleValues.x(),
758  in.y() * mScaleValues.y(),
759  in.z() * mScaleValues.z());
760  }
762  Vec3d applyInverseMap(const Vec3d& in) const
763  {
764  return Vec3d(
765  in.x() * mScaleValuesInverse.x(),
766  in.y() * mScaleValuesInverse.y(),
767  in.z() * mScaleValuesInverse.z());
768  }
770  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
772  Vec3d applyJacobian(const Vec3d& in) const { return applyMap(in); }
773 
775  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
777  Vec3d applyInverseJacobian(const Vec3d& in) const { return applyInverseMap(in); }
778 
781  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
783  Vec3d applyJT(const Vec3d& in) const { return applyMap(in); }
784 
785 
786 
789  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const { return applyIJT(in);}
791  Vec3d applyIJT(const Vec3d& in) const { return applyInverseMap(in); }
793  Mat3d applyIJC(const Mat3d& in) const
794  {
795  Mat3d tmp;
796  for (int i = 0; i < 3; i++) {
797  tmp.setRow(i, in.row(i) * mScaleValuesInverse(i));
798  }
799  for (int i = 0; i < 3; i++) {
800  tmp.setCol(i, tmp.col(i) * mScaleValuesInverse(i));
801  }
802  return tmp;
803  }
804  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d&) const { return applyIJC(in); }
806  double determinant(const Vec3d&) const { return determinant(); }
808  double determinant() const { return mScaleValues.x() * mScaleValues.y() * mScaleValues.z(); }
809 
811  const Vec3d& getScale() const {return mScaleValues;}
812 
814  const Vec3d& getInvScaleSqr() const { return mInvScaleSqr; }
816  const Vec3d& getInvTwiceScale() const { return mInvTwiceScale; }
818  const Vec3d& getInvScale() const { return mScaleValuesInverse; }
819 
821  Vec3d voxelSize() const { return mVoxelSize; }
826  Vec3d voxelSize(const Vec3d&) const { return voxelSize(); }
828 
830  void read(std::istream& is)
831  {
832  mScaleValues.read(is);
833  mVoxelSize.read(is);
834  mScaleValuesInverse.read(is);
835  mInvScaleSqr.read(is);
836  mInvTwiceScale.read(is);
837  }
839  void write(std::ostream& os) const
840  {
841  mScaleValues.write(os);
842  mVoxelSize.write(os);
843  mScaleValuesInverse.write(os);
844  mInvScaleSqr.write(os);
845  mInvTwiceScale.write(os);
846  }
848  std::string str() const
849  {
850  std::ostringstream buffer;
851  buffer << " - scale: " << mScaleValues << std::endl;
852  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
853  return buffer.str();
854  }
855 
856  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
857 
858  bool operator==(const ScaleMap& other) const
859  {
860  // ::eq() uses a tolerance
861  if (!mScaleValues.eq(other.mScaleValues)) { return false; }
862  return true;
863  }
864 
865  bool operator!=(const ScaleMap& other) const { return !(*this == other); }
866 
869  {
870  return AffineMap::Ptr(new AffineMap(math::scale<Mat4d>(mScaleValues)));
871  }
872 
873 
874 
876  MapBase::Ptr preRotate(double radians, Axis axis) const
879  {
880  AffineMap::Ptr affineMap = getAffineMap();
881  affineMap->accumPreRotation(axis, radians);
882  return simplify(affineMap);
883  }
884 
885  MapBase::Ptr preTranslate(const Vec3d& tr) const;
886 
887  MapBase::Ptr preScale(const Vec3d& v) const;
888 
889  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
890  {
891  AffineMap::Ptr affineMap = getAffineMap();
892  affineMap->accumPreShear(axis0, axis1, shear);
893  return simplify(affineMap);
894  }
896 
897 
899  MapBase::Ptr postRotate(double radians, Axis axis) const
902  {
903  AffineMap::Ptr affineMap = getAffineMap();
904  affineMap->accumPostRotation(axis, radians);
905  return simplify(affineMap);
906  }
907 
908  MapBase::Ptr postTranslate(const Vec3d& tr) const;
909 
910  MapBase::Ptr postScale(const Vec3d& v) const;
911 
912  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
913  {
914  AffineMap::Ptr affineMap = getAffineMap();
915  affineMap->accumPostShear(axis0, axis1, shear);
916  return simplify(affineMap);
917  }
919 
920 private:
921  Vec3d mScaleValues, mVoxelSize, mScaleValuesInverse, mInvScaleSqr, mInvTwiceScale;
922 }; // class ScaleMap
923 
924 
928 {
929 public:
930  typedef boost::shared_ptr<UniformScaleMap> Ptr;
931  typedef boost::shared_ptr<const UniformScaleMap> ConstPtr;
932 
934  UniformScaleMap(double scale): ScaleMap(Vec3d(scale, scale, scale)) {}
935  UniformScaleMap(const UniformScaleMap& other): ScaleMap(other) {}
937 
939  static MapBase::Ptr create() { return MapBase::Ptr(new UniformScaleMap()); }
941  MapBase::Ptr copy() const { return MapBase::Ptr(new UniformScaleMap(*this)); }
942 
944  {
945  const Vec3d& invScale = getInvScale();
946  return MapBase::Ptr(new UniformScaleMap( invScale[0]));
947  }
948 
949  static bool isRegistered() { return MapRegistry::isRegistered(UniformScaleMap::mapType()); }
950  static void registerMap()
951  {
952  MapRegistry::registerMap(
953  UniformScaleMap::mapType(),
954  UniformScaleMap::create);
955  }
956 
957  Name type() const { return mapType(); }
958  static Name mapType() { return Name("UniformScaleMap"); }
959 
960  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
961 
962  bool operator==(const UniformScaleMap& other) const { return ScaleMap::operator==(other); }
963  bool operator!=(const UniformScaleMap& other) const { return !(*this == other); }
964 
967  MapBase::Ptr preTranslate(const Vec3d& tr) const;
968 
971  MapBase::Ptr postTranslate(const Vec3d& tr) const;
972 
973 }; // class UniformScaleMap
974 
975 
977 
978 
979 inline MapBase::Ptr
980 ScaleMap::preScale(const Vec3d& v) const
981 {
982  const Vec3d new_scale(v * mScaleValues);
983  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
984  return MapBase::Ptr(new UniformScaleMap(new_scale[0]));
985  } else {
986  return MapBase::Ptr(new ScaleMap(new_scale));
987  }
988 }
989 
990 
991 inline MapBase::Ptr
992 ScaleMap::postScale(const Vec3d& v) const
993 { // pre-post Scale are the same for a scale map
994  return preScale(v);
995 }
996 
997 
1000 {
1001 public:
1002  typedef boost::shared_ptr<TranslationMap> Ptr;
1003  typedef boost::shared_ptr<const TranslationMap> ConstPtr;
1004 
1005  // default constructor is a translation by zero.
1006  TranslationMap(): MapBase(), mTranslation(Vec3d(0,0,0)) {}
1007  TranslationMap(const Vec3d& t): MapBase(), mTranslation(t) {}
1008  TranslationMap(const TranslationMap& other): MapBase(), mTranslation(other.mTranslation) {}
1009 
1011 
1013  static MapBase::Ptr create() { return MapBase::Ptr(new TranslationMap()); }
1015  MapBase::Ptr copy() const { return MapBase::Ptr(new TranslationMap(*this)); }
1016 
1017  MapBase::Ptr inverseMap() const { return MapBase::Ptr(new TranslationMap(-mTranslation)); }
1018 
1019  static bool isRegistered() { return MapRegistry::isRegistered(TranslationMap::mapType()); }
1020 
1021  static void registerMap()
1022  {
1023  MapRegistry::registerMap(
1024  TranslationMap::mapType(),
1025  TranslationMap::create);
1026  }
1027 
1028  Name type() const { return mapType(); }
1029  static Name mapType() { return Name("TranslationMap"); }
1030 
1032  bool isLinear() const { return true; }
1033 
1035  bool hasUniformScale() const { return true; }
1036 
1038  Vec3d applyMap(const Vec3d& in) const { return in + mTranslation; }
1040  Vec3d applyInverseMap(const Vec3d& in) const { return in - mTranslation; }
1042  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
1044  Vec3d applyJacobian(const Vec3d& in) const { return in; }
1045 
1047  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
1049  Vec3d applyInverseJacobian(const Vec3d& in) const { return in; }
1050 
1051 
1054  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
1056  Vec3d applyJT(const Vec3d& in) const { return in; }
1057 
1060  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const { return applyIJT(in);}
1063  Vec3d applyIJT(const Vec3d& in) const {return in;}
1065  Mat3d applyIJC(const Mat3d& mat) const {return mat;}
1066  Mat3d applyIJC(const Mat3d& mat, const Vec3d&, const Vec3d&) const { return applyIJC(mat); }
1067 
1069  double determinant(const Vec3d& ) const { return determinant(); }
1071  double determinant() const { return 1.0; }
1072 
1074  Vec3d voxelSize() const { return Vec3d(1,1,1);}
1076  Vec3d voxelSize(const Vec3d&) const { return voxelSize();}
1077 
1079  const Vec3d& getTranslation() const { return mTranslation; }
1081  void read(std::istream& is) { mTranslation.read(is); }
1083  void write(std::ostream& os) const { mTranslation.write(os); }
1084 
1086  std::string str() const
1087  {
1088  std::ostringstream buffer;
1089  buffer << " - translation: " << mTranslation << std::endl;
1090  return buffer.str();
1091  }
1092 
1093  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1094 
1095  bool operator==(const TranslationMap& other) const
1096  {
1097  // ::eq() uses a tolerance
1098  return mTranslation.eq(other.mTranslation);
1099  }
1100 
1101  bool operator!=(const TranslationMap& other) const { return !(*this == other); }
1102 
1105  {
1106  Mat4d matrix(Mat4d::identity());
1107  matrix.setTranslation(mTranslation);
1108 
1109  AffineMap::Ptr affineMap(new AffineMap(matrix));
1110  return affineMap;
1111  }
1112 
1114  MapBase::Ptr preRotate(double radians, Axis axis) const
1117  {
1118  AffineMap::Ptr affineMap = getAffineMap();
1119  affineMap->accumPreRotation(axis, radians);
1120  return simplify(affineMap);
1121 
1122  }
1124  {
1125  return MapBase::Ptr(new TranslationMap(t + mTranslation));
1126  }
1127 
1128  MapBase::Ptr preScale(const Vec3d& v) const;
1129 
1130  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
1131  {
1132  AffineMap::Ptr affineMap = getAffineMap();
1133  affineMap->accumPreShear(axis0, axis1, shear);
1134  return simplify(affineMap);
1135  }
1137 
1139  MapBase::Ptr postRotate(double radians, Axis axis) const
1142  {
1143  AffineMap::Ptr affineMap = getAffineMap();
1144  affineMap->accumPostRotation(axis, radians);
1145  return simplify(affineMap);
1146 
1147  }
1149  { // post and pre are the same for this
1150  return MapBase::Ptr(new TranslationMap(t + mTranslation));
1151  }
1152 
1153  MapBase::Ptr postScale(const Vec3d& v) const;
1154 
1155  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
1156  {
1157  AffineMap::Ptr affineMap = getAffineMap();
1158  affineMap->accumPostShear(axis0, axis1, shear);
1159  return simplify(affineMap);
1160  }
1162 
1163 private:
1164  Vec3d mTranslation;
1165 }; // class TranslationMap
1166 
1167 
1169 
1170 
1175 {
1176 public:
1177  typedef boost::shared_ptr<ScaleTranslateMap> Ptr;
1178  typedef boost::shared_ptr<const ScaleTranslateMap> ConstPtr;
1179 
1181  MapBase(),
1182  mTranslation(Vec3d(0,0,0)),
1183  mScaleValues(Vec3d(1,1,1)),
1184  mVoxelSize(Vec3d(1,1,1)),
1185  mScaleValuesInverse(Vec3d(1,1,1)),
1186  mInvScaleSqr(1,1,1),
1187  mInvTwiceScale(0.5,0.5,0.5)
1188  {
1189  }
1190 
1191  ScaleTranslateMap(const Vec3d& scale, const Vec3d& translate):
1192  MapBase(),
1193  mTranslation(translate),
1194  mScaleValues(scale),
1195  mVoxelSize(std::abs(scale(0)), std::abs(scale(1)), std::abs(scale(2)))
1196  {
1197  const double determinant = scale[0]* scale[1] * scale[2];
1198  if (std::abs(determinant) < 3.0 * math::Tolerance<double>::value()) {
1199  OPENVDB_THROW(ArithmeticError, "Non-zero scale values required");
1200  }
1201  mScaleValuesInverse = 1.0 / mScaleValues;
1202  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
1203  mInvTwiceScale = mScaleValuesInverse / 2;
1204  }
1205 
1206  ScaleTranslateMap(const ScaleMap& scale, const TranslationMap& translate):
1207  MapBase(),
1208  mTranslation(translate.getTranslation()),
1209  mScaleValues(scale.getScale()),
1210  mVoxelSize(std::abs(mScaleValues(0)),
1211  std::abs(mScaleValues(1)),
1212  std::abs(mScaleValues(2))),
1213  mScaleValuesInverse(1.0 / scale.getScale())
1214  {
1215  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
1216  mInvTwiceScale = mScaleValuesInverse / 2;
1217  }
1218 
1220  MapBase(),
1221  mTranslation(other.mTranslation),
1222  mScaleValues(other.mScaleValues),
1223  mVoxelSize(other.mVoxelSize),
1224  mScaleValuesInverse(other.mScaleValuesInverse),
1225  mInvScaleSqr(other.mInvScaleSqr),
1226  mInvTwiceScale(other.mInvTwiceScale)
1227  {}
1228 
1230 
1234  MapBase::Ptr copy() const { return MapBase::Ptr(new ScaleTranslateMap(*this)); }
1235 
1237  {
1238  return MapBase::Ptr(new ScaleTranslateMap(
1239  mScaleValuesInverse, -mScaleValuesInverse * mTranslation));
1240  }
1241 
1242  static bool isRegistered() { return MapRegistry::isRegistered(ScaleTranslateMap::mapType()); }
1243 
1244  static void registerMap()
1245  {
1246  MapRegistry::registerMap(
1247  ScaleTranslateMap::mapType(),
1248  ScaleTranslateMap::create);
1249  }
1250 
1251  Name type() const { return mapType(); }
1252  static Name mapType() { return Name("ScaleTranslateMap"); }
1253 
1255  bool isLinear() const { return true; }
1256 
1259  bool hasUniformScale() const
1260  {
1261  bool value = isApproxEqual(
1262  std::abs(mScaleValues.x()), std::abs(mScaleValues.y()), double(5e-7));
1263  value = value && isApproxEqual(
1264  std::abs(mScaleValues.x()), std::abs(mScaleValues.z()), double(5e-7));
1265  return value;
1266  }
1267 
1269  Vec3d applyMap(const Vec3d& in) const
1270  {
1271  return Vec3d(
1272  in.x() * mScaleValues.x() + mTranslation.x(),
1273  in.y() * mScaleValues.y() + mTranslation.y(),
1274  in.z() * mScaleValues.z() + mTranslation.z());
1275  }
1277  Vec3d applyInverseMap(const Vec3d& in) const
1278  {
1279  return Vec3d(
1280  (in.x() - mTranslation.x() ) * mScaleValuesInverse.x(),
1281  (in.y() - mTranslation.y() ) * mScaleValuesInverse.y(),
1282  (in.z() - mTranslation.z() ) * mScaleValuesInverse.z());
1283  }
1284 
1286  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
1288  Vec3d applyJacobian(const Vec3d& in) const { return in * mScaleValues; }
1289 
1291  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
1293  Vec3d applyInverseJacobian(const Vec3d& in) const { return in * mScaleValuesInverse; }
1294 
1297  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
1299  Vec3d applyJT(const Vec3d& in) const { return applyJacobian(in); }
1300 
1303  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const { return applyIJT(in);}
1305  Vec3d applyIJT(const Vec3d& in) const
1306  {
1307  return Vec3d(
1308  in.x() * mScaleValuesInverse.x(),
1309  in.y() * mScaleValuesInverse.y(),
1310  in.z() * mScaleValuesInverse.z());
1311  }
1313  Mat3d applyIJC(const Mat3d& in) const
1314  {
1315  Mat3d tmp;
1316  for (int i=0; i<3; i++){
1317  tmp.setRow(i, in.row(i)*mScaleValuesInverse(i));
1318  }
1319  for (int i=0; i<3; i++){
1320  tmp.setCol(i, tmp.col(i)*mScaleValuesInverse(i));
1321  }
1322  return tmp;
1323  }
1324  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d& ) const { return applyIJC(in); }
1325 
1327  double determinant(const Vec3d& ) const { return determinant(); }
1329  double determinant() const { return mScaleValues.x()*mScaleValues.y()*mScaleValues.z(); }
1331  Vec3d voxelSize() const { return mVoxelSize;}
1334  Vec3d voxelSize(const Vec3d&) const { return voxelSize();}
1335 
1337  const Vec3d& getScale() const { return mScaleValues; }
1339  const Vec3d& getTranslation() const { return mTranslation; }
1340 
1342  const Vec3d& getInvScaleSqr() const {return mInvScaleSqr;}
1344  const Vec3d& getInvTwiceScale() const {return mInvTwiceScale;}
1346  const Vec3d& getInvScale() const {return mScaleValuesInverse; }
1347 
1349  void read(std::istream& is)
1350  {
1351  mTranslation.read(is);
1352  mScaleValues.read(is);
1353  mVoxelSize.read(is);
1354  mScaleValuesInverse.read(is);
1355  mInvScaleSqr.read(is);
1356  mInvTwiceScale.read(is);
1357  }
1359  void write(std::ostream& os) const
1360  {
1361  mTranslation.write(os);
1362  mScaleValues.write(os);
1363  mVoxelSize.write(os);
1364  mScaleValuesInverse.write(os);
1365  mInvScaleSqr.write(os);
1366  mInvTwiceScale.write(os);
1367  }
1369  std::string str() const
1370  {
1371  std::ostringstream buffer;
1372  buffer << " - translation: " << mTranslation << std::endl;
1373  buffer << " - scale: " << mScaleValues << std::endl;
1374  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
1375  return buffer.str();
1376  }
1377 
1378  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1379 
1380  bool operator==(const ScaleTranslateMap& other) const
1381  {
1382  // ::eq() uses a tolerance
1383  if (!mScaleValues.eq(other.mScaleValues)) { return false; }
1384  if (!mTranslation.eq(other.mTranslation)) { return false; }
1385  return true;
1386  }
1387 
1388  bool operator!=(const ScaleTranslateMap& other) const { return !(*this == other); }
1389 
1392  {
1393  AffineMap::Ptr affineMap(new AffineMap(math::scale<Mat4d>(mScaleValues)));
1394  affineMap->accumPostTranslation(mTranslation);
1395  return affineMap;
1396  }
1397 
1399  MapBase::Ptr preRotate(double radians, Axis axis) const
1402  {
1403  AffineMap::Ptr affineMap = getAffineMap();
1404  affineMap->accumPreRotation(axis, radians);
1405  return simplify(affineMap);
1406  }
1408  {
1409  const Vec3d& s = mScaleValues;
1410  const Vec3d scaled_trans( t.x() * s.x(),
1411  t.y() * s.y(),
1412  t.z() * s.z() );
1413  return MapBase::Ptr( new ScaleTranslateMap(mScaleValues, mTranslation + scaled_trans));
1414  }
1415 
1416  MapBase::Ptr preScale(const Vec3d& v) const;
1417 
1418  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
1419  {
1420  AffineMap::Ptr affineMap = getAffineMap();
1421  affineMap->accumPreShear(axis0, axis1, shear);
1422  return simplify(affineMap);
1423  }
1425 
1427  MapBase::Ptr postRotate(double radians, Axis axis) const
1430  {
1431  AffineMap::Ptr affineMap = getAffineMap();
1432  affineMap->accumPostRotation(axis, radians);
1433  return simplify(affineMap);
1434  }
1436  {
1437  return MapBase::Ptr( new ScaleTranslateMap(mScaleValues, mTranslation + t));
1438  }
1439 
1440  MapBase::Ptr postScale(const Vec3d& v) const;
1441 
1442  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
1443  {
1444  AffineMap::Ptr affineMap = getAffineMap();
1445  affineMap->accumPostShear(axis0, axis1, shear);
1446  return simplify(affineMap);
1447  }
1449 
1450 private:
1451  Vec3d mTranslation, mScaleValues, mVoxelSize, mScaleValuesInverse,
1452  mInvScaleSqr, mInvTwiceScale;
1453 }; // class ScaleTanslateMap
1454 
1455 
1456 inline MapBase::Ptr
1457 ScaleMap::postTranslate(const Vec3d& t) const
1458 {
1459  return MapBase::Ptr(new ScaleTranslateMap(mScaleValues, t));
1460 }
1461 
1462 
1463 inline MapBase::Ptr
1464 ScaleMap::preTranslate(const Vec3d& t) const
1465 {
1466 
1467  const Vec3d& s = mScaleValues;
1468  const Vec3d scaled_trans( t.x() * s.x(),
1469  t.y() * s.y(),
1470  t.z() * s.z() );
1471  return MapBase::Ptr(new ScaleTranslateMap(mScaleValues, scaled_trans));
1472 }
1473 
1474 
1478 {
1479 public:
1480  typedef boost::shared_ptr<UniformScaleTranslateMap> Ptr;
1481  typedef boost::shared_ptr<const UniformScaleTranslateMap> ConstPtr;
1482 
1484  UniformScaleTranslateMap(double scale, const Vec3d& translate):
1485  ScaleTranslateMap(Vec3d(scale,scale,scale), translate) {}
1487  ScaleTranslateMap(scale.getScale(), translate.getTranslation()) {}
1488 
1491 
1495  MapBase::Ptr copy() const { return MapBase::Ptr(new UniformScaleTranslateMap(*this)); }
1496 
1498  {
1499  const Vec3d& scaleInv = getInvScale();
1500  const Vec3d& trans = getTranslation();
1501  return MapBase::Ptr(new UniformScaleTranslateMap(scaleInv[0], -scaleInv[0] * trans));
1502  }
1503 
1504  static bool isRegistered()
1505  {
1506  return MapRegistry::isRegistered(UniformScaleTranslateMap::mapType());
1507  }
1508 
1509  static void registerMap()
1510  {
1511  MapRegistry::registerMap(
1512  UniformScaleTranslateMap::mapType(),
1513  UniformScaleTranslateMap::create);
1514  }
1515 
1516  Name type() const { return mapType(); }
1517  static Name mapType() { return Name("UniformScaleTranslateMap"); }
1518 
1519  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1520 
1521  bool operator==(const UniformScaleTranslateMap& other) const
1522  {
1523  return ScaleTranslateMap::operator==(other);
1524  }
1525  bool operator!=(const UniformScaleTranslateMap& other) const { return !(*this == other); }
1526 
1530  {
1531  const double scale = this->getScale().x();
1532  const Vec3d new_trans = this->getTranslation() + scale * t;
1533  return MapBase::Ptr( new UniformScaleTranslateMap(scale, new_trans));
1534  }
1535 
1539  {
1540  const double scale = this->getScale().x();
1541  return MapBase::Ptr( new UniformScaleTranslateMap(scale, this->getTranslation() + t));
1542  }
1543 }; // class UniformScaleTanslateMap
1544 
1545 
1546 inline MapBase::Ptr
1547 UniformScaleMap::postTranslate(const Vec3d& t) const
1548 {
1549  const double scale = this->getScale().x();
1550  return MapBase::Ptr(new UniformScaleTranslateMap(scale, t));
1551 }
1552 
1553 
1554 inline MapBase::Ptr
1555 UniformScaleMap::preTranslate(const Vec3d& t) const
1556 {
1557  const double scale = this->getScale().x();
1558  return MapBase::Ptr(new UniformScaleTranslateMap(scale, scale*t));
1559 }
1560 
1561 
1562 inline MapBase::Ptr
1563 TranslationMap::preScale(const Vec3d& v) const
1564 {
1565  if (isApproxEqual(v[0],v[1]) && isApproxEqual(v[0],v[2])) {
1566  return MapBase::Ptr(new UniformScaleTranslateMap(v[0], mTranslation));
1567  } else {
1568  return MapBase::Ptr(new ScaleTranslateMap(v, mTranslation));
1569  }
1570 }
1571 
1572 
1573 inline MapBase::Ptr
1574 TranslationMap::postScale(const Vec3d& v) const
1575 {
1576  if (isApproxEqual(v[0],v[1]) && isApproxEqual(v[0],v[2])) {
1577  return MapBase::Ptr(new UniformScaleTranslateMap(v[0], v[0]*mTranslation));
1578  } else {
1579  const Vec3d trans(mTranslation.x()*v.x(),
1580  mTranslation.y()*v.y(),
1581  mTranslation.z()*v.z());
1582  return MapBase::Ptr(new ScaleTranslateMap(v, trans));
1583  }
1584 }
1585 
1586 
1587 inline MapBase::Ptr
1588 ScaleTranslateMap::preScale(const Vec3d& v) const
1589 {
1590  const Vec3d new_scale( v * mScaleValues );
1591  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
1592  return MapBase::Ptr( new UniformScaleTranslateMap(new_scale[0], mTranslation));
1593  } else {
1594  return MapBase::Ptr( new ScaleTranslateMap(new_scale, mTranslation));
1595  }
1596 }
1597 
1598 
1599 inline MapBase::Ptr
1600 ScaleTranslateMap::postScale(const Vec3d& v) const
1601 {
1602  const Vec3d new_scale( v * mScaleValues );
1603  const Vec3d new_trans( mTranslation.x()*v.x(),
1604  mTranslation.y()*v.y(),
1605  mTranslation.z()*v.z() );
1606 
1607  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
1608  return MapBase::Ptr( new UniformScaleTranslateMap(new_scale[0], new_trans));
1609  } else {
1610  return MapBase::Ptr( new ScaleTranslateMap(new_scale, new_trans));
1611  }
1612 }
1613 
1614 
1616 
1617 
1621 {
1622 public:
1623  typedef boost::shared_ptr<UnitaryMap> Ptr;
1624  typedef boost::shared_ptr<const UnitaryMap> ConstPtr;
1625 
1627  UnitaryMap(): mAffineMap(Mat4d::identity())
1628  {
1629  }
1630 
1631  UnitaryMap(const Vec3d& axis, double radians)
1632  {
1633  Mat3d matrix;
1634  matrix.setToRotation(axis, radians);
1635  mAffineMap = AffineMap(matrix);
1636  }
1637 
1638  UnitaryMap(Axis axis, double radians)
1639  {
1640  Mat4d matrix;
1641  matrix.setToRotation(axis, radians);
1642  mAffineMap = AffineMap(matrix);
1643  }
1644 
1645  UnitaryMap(const Mat3d& m)
1646  {
1647  // test that the mat3 is a rotation || reflection
1648  if (!isUnitary(m)) {
1649  OPENVDB_THROW(ArithmeticError, "Matrix initializing unitary map was not unitary");
1650  }
1651 
1652  Mat4d matrix(Mat4d::identity());
1653  matrix.setMat3(m);
1654  mAffineMap = AffineMap(matrix);
1655  }
1656 
1657  UnitaryMap(const Mat4d& m)
1658  {
1659  if (!isInvertible(m)) {
1661  "4x4 Matrix initializing unitary map was not unitary: not invertible");
1662  }
1663 
1664  if (!isAffine(m)) {
1666  "4x4 Matrix initializing unitary map was not unitary: not affine");
1667  }
1668 
1669  if (hasTranslation(m)) {
1671  "4x4 Matrix initializing unitary map was not unitary: had translation");
1672  }
1673 
1674  if (!isUnitary(m.getMat3())) {
1676  "4x4 Matrix initializing unitary map was not unitary");
1677  }
1678 
1679  mAffineMap = AffineMap(m);
1680  }
1681 
1682  UnitaryMap(const UnitaryMap& other):
1683  MapBase(other),
1684  mAffineMap(other.mAffineMap)
1685  {
1686  }
1687 
1688  UnitaryMap(const UnitaryMap& first, const UnitaryMap& second):
1689  mAffineMap(*(first.getAffineMap()), *(second.getAffineMap()))
1690  {
1691  }
1692 
1695  static MapBase::Ptr create() { return MapBase::Ptr(new UnitaryMap()); }
1697  MapBase::Ptr copy() const { return MapBase::Ptr(new UnitaryMap(*this)); }
1698 
1700  {
1701  return MapBase::Ptr(new UnitaryMap(mAffineMap.getMat4().inverse()));
1702  }
1703 
1704  static bool isRegistered() { return MapRegistry::isRegistered(UnitaryMap::mapType()); }
1705 
1706  static void registerMap()
1707  {
1708  MapRegistry::registerMap(
1709  UnitaryMap::mapType(),
1710  UnitaryMap::create);
1711  }
1712 
1714  Name type() const { return mapType(); }
1716  static Name mapType() { return Name("UnitaryMap"); }
1717 
1719  bool isLinear() const { return true; }
1720 
1722  bool hasUniformScale() const { return true; }
1723 
1724  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1725 
1726  bool operator==(const UnitaryMap& other) const
1727  {
1728  // compare underlying linear map.
1729  if (mAffineMap!=other.mAffineMap) return false;
1730  return true;
1731  }
1732 
1733  bool operator!=(const UnitaryMap& other) const { return !(*this == other); }
1735  Vec3d applyMap(const Vec3d& in) const { return mAffineMap.applyMap(in); }
1737  Vec3d applyInverseMap(const Vec3d& in) const { return mAffineMap.applyInverseMap(in); }
1738 
1739  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
1741  Vec3d applyJacobian(const Vec3d& in) const { return mAffineMap.applyJacobian(in); }
1742 
1744  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
1746  Vec3d applyInverseJacobian(const Vec3d& in) const { return mAffineMap.applyInverseJacobian(in); }
1747 
1748 
1751  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
1753  Vec3d applyJT(const Vec3d& in) const {
1754  // The transpose of the unitary map is its inverse
1755  return applyInverseMap(in);
1756  }
1757 
1758 
1761  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const { return applyIJT(in);}
1763  Vec3d applyIJT(const Vec3d& in) const { return mAffineMap.applyIJT(in); }
1765  Mat3d applyIJC(const Mat3d& in) const { return mAffineMap.applyIJC(in); }
1766  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d& ) const { return applyIJC(in); }
1768  double determinant(const Vec3d& ) const { return determinant(); }
1770  double determinant() const { return mAffineMap.determinant(); }
1771 
1772 
1777  Vec3d voxelSize() const { return mAffineMap.voxelSize();}
1778  Vec3d voxelSize(const Vec3d&) const { return voxelSize();}
1779 
1781  void read(std::istream& is)
1782  {
1783  mAffineMap.read(is);
1784  }
1785 
1787  void write(std::ostream& os) const
1788  {
1789  mAffineMap.write(os);
1790  }
1792  std::string str() const
1793  {
1794  std::ostringstream buffer;
1795  buffer << mAffineMap.str();
1796  return buffer.str();
1797  }
1799  AffineMap::Ptr getAffineMap() const { return AffineMap::Ptr(new AffineMap(mAffineMap)); }
1800 
1802  MapBase::Ptr preRotate(double radians, Axis axis) const
1805  {
1806  UnitaryMap first(axis, radians);
1807  UnitaryMap::Ptr unitaryMap(new UnitaryMap(first, *this));
1808  return boost::static_pointer_cast<MapBase, UnitaryMap>(unitaryMap);
1809  }
1811  {
1812  AffineMap::Ptr affineMap = getAffineMap();
1813  affineMap->accumPreTranslation(t);
1814  return simplify(affineMap);
1815  }
1816  MapBase::Ptr preScale(const Vec3d& v) const
1817  {
1818  AffineMap::Ptr affineMap = getAffineMap();
1819  affineMap->accumPreScale(v);
1820  return simplify(affineMap);
1821  }
1822  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
1823  {
1824  AffineMap::Ptr affineMap = getAffineMap();
1825  affineMap->accumPreShear(axis0, axis1, shear);
1826  return simplify(affineMap);
1827  }
1829 
1830 
1832  MapBase::Ptr postRotate(double radians, Axis axis) const
1835  {
1836  UnitaryMap second(axis, radians);
1837  UnitaryMap::Ptr unitaryMap(new UnitaryMap(*this, second));
1838  return boost::static_pointer_cast<MapBase, UnitaryMap>(unitaryMap);
1839  }
1841  {
1842  AffineMap::Ptr affineMap = getAffineMap();
1843  affineMap->accumPostTranslation(t);
1844  return simplify(affineMap);
1845  }
1846  MapBase::Ptr postScale(const Vec3d& v) const
1847  {
1848  AffineMap::Ptr affineMap = getAffineMap();
1849  affineMap->accumPostScale(v);
1850  return simplify(affineMap);
1851  }
1852  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
1853  {
1854  AffineMap::Ptr affineMap = getAffineMap();
1855  affineMap->accumPostShear(axis0, axis1, shear);
1856  return simplify(affineMap);
1857  }
1859 
1860 private:
1861  AffineMap mAffineMap;
1862 }; // class UnitaryMap
1863 
1864 
1866 
1867 
1875 {
1876 public:
1877  typedef boost::shared_ptr<NonlinearFrustumMap> Ptr;
1878  typedef boost::shared_ptr<const NonlinearFrustumMap> ConstPtr;
1879 
1881  MapBase(),
1882  mBBox(Vec3d(0), Vec3d(1)),
1883  mTaper(1),
1884  mDepth(1)
1885  {
1886  init();
1887  }
1888 
1892  NonlinearFrustumMap(const BBoxd& bb, double taper, double depth):
1893  MapBase(),mBBox(bb), mTaper(taper), mDepth(depth)
1894  {
1895  init();
1896  }
1897 
1903  NonlinearFrustumMap(const BBoxd& bb, double taper, double depth,
1904  const MapBase::Ptr& secondMap):
1905  mBBox(bb), mTaper(taper), mDepth(depth)
1906  {
1907  if (!secondMap->isLinear() ) {
1909  "The second map in the Frustum transfrom must be linear");
1910  }
1911  mSecondMap = *( secondMap->getAffineMap() );
1912  init();
1913  }
1914 
1916  MapBase(),
1917  mBBox(other.mBBox),
1918  mTaper(other.mTaper),
1919  mDepth(other.mDepth),
1920  mSecondMap(other.mSecondMap),
1921  mHasSimpleAffine(other.mHasSimpleAffine)
1922  {
1923  init();
1924  }
1925 
1941  NonlinearFrustumMap(const Vec3d& position,
1942  const Vec3d& direction,
1943  const Vec3d& up,
1944  double aspect /* width / height */,
1945  double z_near, double depth,
1946  Coord::ValueType x_count, Coord::ValueType z_count) {
1947 
1951  if (!(depth > 0)) {
1953  "The frustum depth must be non-zero and positive");
1954  }
1955  if (!(up.length() > 0)) {
1957  "The frustum height must be non-zero and positive");
1958  }
1959  if (!(aspect > 0)) {
1961  "The frustum aspect ratio must be non-zero and positive");
1962  }
1963  if (!(isApproxEqual(up.dot(direction), 0.))) {
1965  "The frustum up orientation must be perpendicular to into-frustum direction");
1966  }
1967 
1968  double near_plane_height = 2 * up.length();
1969  double near_plane_width = aspect * near_plane_height;
1970 
1971  Coord::ValueType y_count = static_cast<int>(Round(x_count / aspect));
1972 
1973  mBBox = BBoxd(Vec3d(0,0,0), Vec3d(x_count, y_count, z_count));
1974  mDepth = depth / near_plane_width; // depth non-dimensionalized on width
1975  double gamma = near_plane_width / z_near;
1976  mTaper = 1./(mDepth*gamma + 1.);
1977 
1978  Vec3d direction_unit = direction;
1979  direction_unit.normalize();
1980 
1981  Mat4d r1(Mat4d::identity());
1982  r1.setToRotation(/*from*/Vec3d(0,0,1), /*to */direction_unit);
1983  Mat4d r2(Mat4d::identity());
1984  Vec3d temp = r1.inverse().transform(up);
1985  r2.setToRotation(/*from*/Vec3d(0,1,0), /*to*/temp );
1986  Mat4d scale = math::scale<Mat4d>(
1987  Vec3d(near_plane_width, near_plane_width, near_plane_width));
1988 
1989  // move the near plane to origin, rotate to align with axis, and scale down
1990  // T_inv * R1_inv * R2_inv * scale_inv
1991  Mat4d mat = scale * r2 * r1;
1992  mat.setTranslation(position + z_near*direction_unit);
1993 
1994  mSecondMap = AffineMap(mat);
1995 
1996  init();
1997  }
1998 
2003  MapBase::Ptr copy() const { return MapBase::Ptr(new NonlinearFrustumMap(*this)); }
2004 
2009  {
2011  "inverseMap() is not implemented for NonlinearFrustumMap");
2012  }
2013  static bool isRegistered() { return MapRegistry::isRegistered(NonlinearFrustumMap::mapType()); }
2014 
2015  static void registerMap()
2016  {
2017  MapRegistry::registerMap(
2018  NonlinearFrustumMap::mapType(),
2019  NonlinearFrustumMap::create);
2020  }
2022  Name type() const { return mapType(); }
2024  static Name mapType() { return Name("NonlinearFrustumMap"); }
2025 
2027  bool isLinear() const { return false; }
2028 
2030  bool hasUniformScale() const { return false; }
2031 
2033  bool isIdentity() const
2034  {
2035  // The frustum can only be consistent with a linear map if the taper value is 1
2036  if (!isApproxEqual(mTaper, double(1)) ) return false;
2037 
2038  // There are various ways an identity can decomposed between the two parts of the
2039  // map. Best to just check that the principle vectors are stationary.
2040  const Vec3d e1(1,0,0);
2041  if (!applyMap(e1).eq(e1)) return false;
2042 
2043  const Vec3d e2(0,1,0);
2044  if (!applyMap(e2).eq(e2)) return false;
2045 
2046  const Vec3d e3(0,0,1);
2047  if (!applyMap(e3).eq(e3)) return false;
2048 
2049  return true;
2050  }
2051 
2052  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
2053 
2054  bool operator==(const NonlinearFrustumMap& other) const
2055  {
2056  if (mBBox!=other.mBBox) return false;
2057  if (!isApproxEqual(mTaper, other.mTaper)) return false;
2058  if (!isApproxEqual(mDepth, other.mDepth)) return false;
2059 
2060  // Two linear transforms are equivalent iff they have the same translation
2061  // and have the same affects on orthongal spanning basis check translation
2062  Vec3d e(0,0,0);
2063  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2065  e(0) = 1;
2066  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2067  e(0) = 0;
2068  e(1) = 1;
2069  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2070  e(1) = 0;
2071  e(2) = 1;
2072  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2073  return true;
2074  }
2075 
2076  bool operator!=(const NonlinearFrustumMap& other) const { return !(*this == other); }
2077 
2079  Vec3d applyMap(const Vec3d& in) const
2080  {
2081  return mSecondMap.applyMap(applyFrustumMap(in));
2082  }
2083 
2085  Vec3d applyInverseMap(const Vec3d& in) const
2086  {
2087  return applyFrustumInverseMap(mSecondMap.applyInverseMap(in));
2088  }
2090  Vec3d applyJacobian(const Vec3d& in) const { return mSecondMap.applyJacobian(in); }
2092  Vec3d applyJacobian(const Vec3d& in, const Vec3d& isloc) const
2093  {
2094  // Move the center of the x-face of the bbox
2095  // to the origin in index space.
2096  Vec3d centered(isloc);
2097  centered = centered - mBBox.min();
2098  centered.x() -= mXo;
2099  centered.y() -= mYo;
2100 
2101  // scale the z-direction on depth / K count
2102  const double zprime = centered.z()*mDepthOnLz;
2103 
2104  const double scale = (mGamma * zprime + 1.) / mLx;
2105  const double scale2 = mGamma * mDepthOnLz / mLx;
2106 
2107  const Vec3d tmp(scale * in.x() + scale2 * centered.x()* in.z(),
2108  scale * in.y() + scale2 * centered.y()* in.z(),
2109  mDepthOnLz * in.z());
2110 
2111  return mSecondMap.applyJacobian(tmp);
2112  }
2113 
2114 
2116  Vec3d applyInverseJacobian(const Vec3d& in) const { return mSecondMap.applyInverseJacobian(in); }
2118  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d& isloc) const {
2119 
2120  // Move the center of the x-face of the bbox
2121  // to the origin in index space.
2122  Vec3d centered(isloc);
2123  centered = centered - mBBox.min();
2124  centered.x() -= mXo;
2125  centered.y() -= mYo;
2126 
2127  // scale the z-direction on depth / K count
2128  const double zprime = centered.z()*mDepthOnLz;
2129 
2130  const double scale = (mGamma * zprime + 1.) / mLx;
2131  const double scale2 = mGamma * mDepthOnLz / mLx;
2132 
2133 
2134  Vec3d out = mSecondMap.applyInverseJacobian(in);
2135 
2136  out.x() = (out.x() - scale2 * centered.x() * out.z() / mDepthOnLz) / scale;
2137  out.y() = (out.y() - scale2 * centered.y() * out.z() / mDepthOnLz) / scale;
2138  out.z() = out.z() / mDepthOnLz;
2139 
2140  return out;
2141  }
2142 
2143 
2144 
2148  Vec3d applyJT(const Vec3d& in, const Vec3d& isloc) const {
2149  const Vec3d tmp = mSecondMap.applyJT(in);
2150  // Move the center of the x-face of the bbox
2151  // to the origin in index space.
2152  Vec3d centered(isloc);
2153  centered = centered - mBBox.min();
2154  centered.x() -= mXo;
2155  centered.y() -= mYo;
2156 
2157  // scale the z-direction on depth / K count
2158  const double zprime = centered.z()*mDepthOnLz;
2159 
2160  const double scale = (mGamma * zprime + 1.) / mLx;
2161  const double scale2 = mGamma * mDepthOnLz / mLx;
2162 
2163  return Vec3d(scale * tmp.x(),
2164  scale * tmp.y(),
2165  scale2 * centered.x()* tmp.x() +
2166  scale2 * centered.y()* tmp.y() +
2167  mDepthOnLz * tmp.z());
2168  }
2170  Vec3d applyJT(const Vec3d& in) const {
2171  return mSecondMap.applyJT(in);
2172  }
2173 
2175  Vec3d applyIJT(const Vec3d& in) const { return mSecondMap.applyIJT(in); }
2176 
2177  // the Jacobian of the nonlinear part of the transform is a sparse matrix
2178  // Jacobian^(-T) =
2179  //
2180  // (Lx)( 1/s 0 0 )
2181  // ( 0 1/s 0 )
2182  // ( -(x-xo)g/(sLx) -(y-yo)g/(sLx) Lz/(Depth Lx) )
2185  Vec3d applyIJT(const Vec3d& d1_is, const Vec3d& ijk) const
2186  {
2187  const Vec3d loc = applyFrustumMap(ijk);
2188  const double s = mGamma * loc.z() + 1.;
2189 
2190  // verify that we aren't at the singularity
2191  if (isApproxEqual(s, 0.)) {
2192  OPENVDB_THROW(ArithmeticError, "Tried to evaluate the frustum transform"
2193  " at the singular focal point (e.g. camera)");
2194  }
2195 
2196  const double sinv = 1.0/s; // 1/(z*gamma + 1)
2197  const double pt0 = mLx * sinv; // Lx / (z*gamma +1)
2198  const double pt1 = mGamma * pt0; // gamma * Lx / ( z*gamma +1)
2199  const double pt2 = pt1 * sinv; // gamma * Lx / ( z*gamma +1)**2
2200 
2201  const Mat3d& jacinv = mSecondMap.getConstJacobianInv();
2202 
2203  // compute \frac{\partial E_i}{\partial x_j}
2204  Mat3d gradE(Mat3d::zero());
2205  for (int j = 0; j < 3; ++j ) {
2206  gradE(0,j) = pt0 * jacinv(0,j) - pt2 * loc.x()*jacinv(2,j);
2207  gradE(1,j) = pt0 * jacinv(1,j) - pt2 * loc.y()*jacinv(2,j);
2208  gradE(2,j) = (1./mDepthOnLz) * jacinv(2,j);
2209  }
2210 
2211  Vec3d result;
2212  for (int i = 0; i < 3; ++i) {
2213  result(i) = d1_is(0) * gradE(0,i) + d1_is(1) * gradE(1,i) + d1_is(2) * gradE(2,i);
2214  }
2215 
2216  return result;
2217 
2218  }
2219 
2221  Mat3d applyIJC(const Mat3d& in) const { return mSecondMap.applyIJC(in); }
2226  Mat3d applyIJC(const Mat3d& d2_is, const Vec3d& d1_is, const Vec3d& ijk) const
2227  {
2228  const Vec3d loc = applyFrustumMap(ijk);
2229 
2230  const double s = mGamma * loc.z() + 1.;
2231 
2232  // verify that we aren't at the singularity
2233  if (isApproxEqual(s, 0.)) {
2234  OPENVDB_THROW(ArithmeticError, "Tried to evaluate the frustum transform"
2235  " at the singular focal point (e.g. camera)");
2236  }
2237 
2238  // precompute
2239  const double sinv = 1.0/s; // 1/(z*gamma + 1)
2240  const double pt0 = mLx * sinv; // Lx / (z*gamma +1)
2241  const double pt1 = mGamma * pt0; // gamma * Lx / ( z*gamma +1)
2242  const double pt2 = pt1 * sinv; // gamma * Lx / ( z*gamma +1)**2
2243  const double pt3 = pt2 * sinv; // gamma * Lx / ( z*gamma +1)**3
2244 
2245  const Mat3d& jacinv = mSecondMap.getConstJacobianInv();
2246 
2247  // compute \frac{\partial^2 E_i}{\partial x_j \partial x_k}
2248 
2249  Mat3d matE0(Mat3d::zero());
2250  Mat3d matE1(Mat3d::zero()); // matE2 = 0
2251  for(int j = 0; j < 3; j++) {
2252  for (int k = 0; k < 3; k++) {
2253 
2254  const double pt4 = 2. * jacinv(2,j) * jacinv(2,k) * pt3;
2255 
2256  matE0(j,k) = -(jacinv(0,j) * jacinv(2,k) + jacinv(2,j) * jacinv(0,k)) * pt2 +
2257  pt4 * loc.x();
2258 
2259  matE1(j,k) = -(jacinv(1,j) * jacinv(2,k) + jacinv(2,j) * jacinv(1,k)) * pt2 +
2260  pt4 * loc.y();
2261  }
2262  }
2263 
2264  // compute \frac{\partial E_i}{\partial x_j}
2265  Mat3d gradE(Mat3d::zero());
2266  for (int j = 0; j < 3; ++j ) {
2267  gradE(0,j) = pt0 * jacinv(0,j) - pt2 * loc.x()*jacinv(2,j);
2268  gradE(1,j) = pt0 * jacinv(1,j) - pt2 * loc.y()*jacinv(2,j);
2269  gradE(2,j) = (1./mDepthOnLz) * jacinv(2,j);
2270  }
2271 
2272  Mat3d result(Mat3d::zero());
2273  // compute \fac{\partial E_j}{\partial x_m} \fac{\partial E_i}{\partial x_n}
2274  // \frac{\partial^2 input}{\partial E_i \partial E_j}
2275  for (int m = 0; m < 3; ++m ) {
2276  for ( int n = 0; n < 3; ++n) {
2277  for (int i = 0; i < 3; ++i ) {
2278  for (int j = 0; j < 3; ++j) {
2279  result(m, n) += gradE(j, m) * gradE(i, n) * d2_is(i, j);
2280  }
2281  }
2282  }
2283  }
2284 
2285  for (int m = 0; m < 3; ++m ) {
2286  for ( int n = 0; n < 3; ++n) {
2287  result(m, n) +=
2288  matE0(m, n) * d1_is(0) + matE1(m, n) * d1_is(1);// + matE2(m, n) * d1_is(2);
2289  }
2290  }
2291 
2292  return result;
2293  }
2294 
2296  double determinant() const {return mSecondMap.determinant();} // no implementation
2297 
2300  double determinant(const Vec3d& loc) const
2301  {
2302  double s = mGamma * loc.z() + 1.0;
2303  double frustum_determinant = s * s * mDepthOnLzLxLx;
2304  return mSecondMap.determinant() * frustum_determinant;
2305  }
2306 
2309  {
2310  const Vec3d loc( 0.5*(mBBox.min().x() + mBBox.max().x()),
2311  0.5*(mBBox.min().y() + mBBox.max().y()),
2312  mBBox.min().z());
2313 
2314  return voxelSize(loc);
2315 
2316  }
2317 
2322  Vec3d voxelSize(const Vec3d& loc) const
2323  {
2324  Vec3d out, pos = applyMap(loc);
2325  out(0) = (applyMap(loc + Vec3d(1,0,0)) - pos).length();
2326  out(1) = (applyMap(loc + Vec3d(0,1,0)) - pos).length();
2327  out(2) = (applyMap(loc + Vec3d(0,0,1)) - pos).length();
2328  return out;
2329  }
2330 
2331  AffineMap::Ptr getAffineMap() const { return mSecondMap.getAffineMap(); }
2332 
2334  void setTaper(double t) { mTaper = t; init();}
2336  double getTaper() const { return mTaper; }
2338  void setDepth(double d) { mDepth = d; init();}
2340  double getDepth() const { return mDepth; }
2341  // gamma a non-dimensional number: nearplane x-width / camera to near plane distance
2342  double getGamma() const { return mGamma; }
2343 
2345  const BBoxd& getBBox() const { return mBBox; }
2346 
2348  const AffineMap& secondMap() const { return mSecondMap; }
2351  bool isValid() const { return !mBBox.empty();}
2352 
2354  bool hasSimpleAffine() const { return mHasSimpleAffine; }
2355 
2357  void read(std::istream& is)
2358  {
2359  // for backward compatibility with earlier version
2361  CoordBBox bb;
2362  bb.read(is);
2363  mBBox = BBoxd(bb.min().asVec3d(), bb.max().asVec3d());
2364  } else {
2365  mBBox.read(is);
2366  }
2367 
2368  is.read(reinterpret_cast<char*>(&mTaper), sizeof(double));
2369  is.read(reinterpret_cast<char*>(&mDepth), sizeof(double));
2370 
2371  // Read the second maps type.
2372  Name type = readString(is);
2373 
2374  // Check if the map has been registered.
2375  if(!MapRegistry::isRegistered(type)) {
2376  OPENVDB_THROW(KeyError, "Map " << type << " is not registered");
2377  }
2378 
2379  // Create the second map of the type and then read it in.
2380  MapBase::Ptr proxy = math::MapRegistry::createMap(type);
2381  proxy->read(is);
2382  mSecondMap = *(proxy->getAffineMap());
2383  init();
2384  }
2385 
2387  void write(std::ostream& os) const
2388  {
2389  mBBox.write(os);
2390  os.write(reinterpret_cast<const char*>(&mTaper), sizeof(double));
2391  os.write(reinterpret_cast<const char*>(&mDepth), sizeof(double));
2392 
2393  writeString(os, mSecondMap.type());
2394  mSecondMap.write(os);
2395  }
2396 
2398  std::string str() const
2399  {
2400  std::ostringstream buffer;
2401  buffer << " - taper: " << mTaper << std::endl;
2402  buffer << " - depth: " << mDepth << std::endl;
2403  buffer << " SecondMap: "<< mSecondMap.type() << std::endl;
2404  buffer << mSecondMap.str() << std::endl;
2405  return buffer.str();
2406  }
2407 
2409  MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const
2412  {
2413  return MapBase::Ptr(
2414  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preRotate(radians, axis)));
2415  }
2417  {
2418  return MapBase::Ptr(
2419  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preTranslate(t)));
2420  }
2421  MapBase::Ptr preScale(const Vec3d& s) const
2422  {
2423  return MapBase::Ptr(
2424  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preScale(s)));
2425  }
2426  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
2427  {
2428  return MapBase::Ptr(new NonlinearFrustumMap(
2429  mBBox, mTaper, mDepth, mSecondMap.preShear(shear, axis0, axis1)));
2430  }
2432 
2434  MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const
2437  {
2438  return MapBase::Ptr(
2439  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postRotate(radians, axis)));
2440  }
2442  {
2443  return MapBase::Ptr(
2444  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postTranslate(t)));
2445  }
2446  MapBase::Ptr postScale(const Vec3d& s) const
2447  {
2448  return MapBase::Ptr(
2449  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postScale(s)));
2450  }
2451  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
2452  {
2453  return MapBase::Ptr(new NonlinearFrustumMap(
2454  mBBox, mTaper, mDepth, mSecondMap.postShear(shear, axis0, axis1)));
2455  }
2457 
2458 private:
2459  void init()
2460  {
2461  // set up as a frustum
2462  mLx = mBBox.extents().x();
2463  mLy = mBBox.extents().y();
2464  mLz = mBBox.extents().z();
2465 
2466  if (isApproxEqual(mLx,0.) || isApproxEqual(mLy,0.) || isApproxEqual(mLz,0.) ) {
2467  OPENVDB_THROW(ArithmeticError, "The index space bounding box"
2468  " must have at least two index points in each direction.");
2469  }
2470 
2471  mXo = 0.5* mLx;
2472  mYo = 0.5* mLy;
2473 
2474  // mDepth is non-dimensionalized on near
2475  mGamma = (1./mTaper - 1) / mDepth;
2476 
2477  mDepthOnLz = mDepth/mLz;
2478  mDepthOnLzLxLx = mDepthOnLz/(mLx * mLx);
2479 
2481  mHasSimpleAffine = true;
2482  Vec3d tmp = mSecondMap.voxelSize();
2483 
2485  if (!isApproxEqual(tmp(0), tmp(1))) { mHasSimpleAffine = false; return; }
2486  if (!isApproxEqual(tmp(0), tmp(2))) { mHasSimpleAffine = false; return; }
2487 
2488  Vec3d trans = mSecondMap.applyMap(Vec3d(0,0,0));
2490  Vec3d tmp1 = mSecondMap.applyMap(Vec3d(1,0,0)) - trans;
2491  Vec3d tmp2 = mSecondMap.applyMap(Vec3d(0,1,0)) - trans;
2492  Vec3d tmp3 = mSecondMap.applyMap(Vec3d(0,0,1)) - trans;
2493 
2495  if (!isApproxEqual(tmp1.dot(tmp2), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2496  if (!isApproxEqual(tmp2.dot(tmp3), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2497  if (!isApproxEqual(tmp3.dot(tmp1), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2498  }
2499 
2500  Vec3d applyFrustumMap(const Vec3d& in) const
2501  {
2502 
2503  // Move the center of the x-face of the bbox
2504  // to the origin in index space.
2505  Vec3d out(in);
2506  out = out - mBBox.min();
2507  out.x() -= mXo;
2508  out.y() -= mYo;
2509 
2510  // scale the z-direction on depth / K count
2511  out.z() *= mDepthOnLz;
2512 
2513  double scale = (mGamma * out.z() + 1.)/ mLx;
2514 
2515  // scale the x-y on the length I count and apply tapper
2516  out.x() *= scale ;
2517  out.y() *= scale ;
2518 
2519  return out;
2520  }
2521 
2522  Vec3d applyFrustumInverseMap(const Vec3d& in) const
2523  {
2524  // invert taper and resize: scale = 1/( (z+1)/2 (mt-1) + 1)
2525  Vec3d out(in);
2526  double invScale = mLx / (mGamma * out.z() + 1.);
2527  out.x() *= invScale;
2528  out.y() *= invScale;
2529 
2530  out.x() += mXo;
2531  out.y() += mYo;
2532 
2533  out.z() /= mDepthOnLz;
2534 
2535  // move back
2536  out = out + mBBox.min();
2537  return out;
2538  }
2539 
2540  // bounding box in index space used in Frustum transforms.
2541  BBoxd mBBox;
2542 
2543  // taper value used in constructing Frustums.
2544  double mTaper;
2545  double mDepth;
2546 
2547  // defines the second map
2548  AffineMap mSecondMap;
2549 
2550  // these are derived from the above.
2551  double mLx, mLy, mLz;
2552  double mXo, mYo, mGamma, mDepthOnLz, mDepthOnLzLxLx;
2553 
2554  // true: if the mSecondMap is linear and has no shear, and has no non-uniform scale
2555  bool mHasSimpleAffine;
2556 }; // class NonlinearFrustumMap
2557 
2558 
2560 
2561 
2565 template<typename FirstMapType, typename SecondMapType>
2566 class CompoundMap
2567 {
2568 public:
2570 
2571  typedef boost::shared_ptr<MyType> Ptr;
2572  typedef boost::shared_ptr<const MyType> ConstPtr;
2573 
2574 
2575  CompoundMap() { updateAffineMatrix(); }
2576 
2577  CompoundMap(const FirstMapType& f, const SecondMapType& s): mFirstMap(f), mSecondMap(s)
2578  {
2579  updateAffineMatrix();
2580  }
2581 
2582  CompoundMap(const MyType& other):
2583  mFirstMap(other.mFirstMap),
2584  mSecondMap(other.mSecondMap),
2585  mAffineMap(other.mAffineMap)
2586  {}
2587 
2588  Name type() const { return mapType(); }
2589  static Name mapType()
2590  {
2591  return (FirstMapType::mapType() + Name(":") + SecondMapType::mapType());
2592  }
2593 
2594  bool operator==(const MyType& other) const
2595  {
2596  if (mFirstMap != other.mFirstMap) return false;
2597  if (mSecondMap != other.mSecondMap) return false;
2598  if (mAffineMap != other.mAffineMap) return false;
2599  return true;
2600  }
2601 
2602  bool operator!=(const MyType& other) const { return !(*this == other); }
2603 
2604  MyType& operator=(const MyType& other)
2605  {
2606  mFirstMap = other.mFirstMap;
2607  mSecondMap = other.mSecondMap;
2608  mAffineMap = other.mAffineMap;
2609  return *this;
2610  }
2611 
2612  bool isIdentity() const
2613  {
2615  return mAffineMap.isIdentity();
2616  } else {
2617  return mFirstMap.isIdentity()&&mSecondMap.isIdentity();
2618  }
2619  }
2620 
2621  bool isDiagonal() const {
2623  return mAffineMap.isDiagonal();
2624  } else {
2625  return mFirstMap.isDiagonal()&&mSecondMap.isDiagonal();
2626  }
2627  }
2628 
2630  {
2632  AffineMap::Ptr affine(new AffineMap(mAffineMap));
2633  return affine;
2634  } else {
2636  "Constant affine matrix representation not possible for this nonlinear map");
2637  }
2638  }
2639 
2640  // direct decompotion
2641  const FirstMapType& firstMap() const { return mFirstMap; }
2642  const SecondMapType& secondMap() const {return mSecondMap; }
2643 
2644  void setFirstMap(const FirstMapType& first) { mFirstMap = first; updateAffineMatrix(); }
2645  void setSecondMap(const SecondMapType& second) { mSecondMap = second; updateAffineMatrix(); }
2646 
2647  void read(std::istream& is)
2648  {
2649  mAffineMap.read(is);
2650  mFirstMap.read(is);
2651  mSecondMap.read(is);
2652  }
2653  void write(std::ostream& os) const
2654  {
2655  mAffineMap.write(os);
2656  mFirstMap.write(os);
2657  mSecondMap.write(os);
2658  }
2659 
2660 private:
2661  void updateAffineMatrix()
2662  {
2664  // both maps need to be linear, these methods are only defined for linear maps
2665  AffineMap::Ptr first = mFirstMap.getAffineMap();
2666  AffineMap::Ptr second= mSecondMap.getAffineMap();
2667  mAffineMap = AffineMap(*first, *second);
2668  }
2669  }
2670 
2671  FirstMapType mFirstMap;
2672  SecondMapType mSecondMap;
2673  // used for acceleration
2674  AffineMap mAffineMap;
2675 }; // class CompoundMap
2676 
2677 } // namespace math
2678 } // namespace OPENVDB_VERSION_NAME
2679 } // namespace openvdb
2680 
2681 #endif // OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
2682 
2683 // Copyright (c) 2012-2015 DreamWorks Animation LLC
2684 // All rights reserved. This software is distributed under the
2685 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
const FirstMapType & firstMap() const
Definition: Maps.h:2641
Vec3< T > col(int j) const
Get jth column, e.g. Vec3d v = m.col(0);.
Definition: Mat3.h:184
Vec3d voxelSize(const Vec3d &loc) const
Returns the lengths of the images of the three segments from loc to loc + (1,0,0), from loc to loc + (0,1,0) and from loc to loc + (0,0,1)
Definition: Maps.h:2322
void write(std::ostream &os) const
write serialization
Definition: Maps.h:1359
void read(std::istream &is)
Definition: Maps.h:2647
bool operator==(const MyType &other) const
Definition: Maps.h:2594
const Vec3d & getScale() const
Returns the scale values.
Definition: Maps.h:1337
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:775
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropiate operation to the l...
Definition: Maps.h:2451
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:450
double determinant(const Vec3d &) const
Return 1.
Definition: Maps.h:1069
double determinant() const
Return the product of the scale values.
Definition: Maps.h:808
NonlinearFrustumMap(const NonlinearFrustumMap &other)
Definition: Maps.h:1915
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:195
NonlinearFrustumMap(const BBoxd &bb, double taper, double depth, const MapBase::Ptr &secondMap)
Constructor that takes an index-space bounding box to be mapped into a frustum with a given depth and...
Definition: Maps.h:1903
double determinant() const
Return the determinant of the Jacobian.
Definition: Maps.h:479
double determinant(const Vec3d &) const
Return the determinant of the Jacobian, ignores argument.
Definition: Maps.h:477
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:1054
Vec3d applyMap(const Vec3d &in) const
Return the image of under the map.
Definition: Maps.h:1269
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1236
AffineMap(const Mat4d &m)
Definition: Maps.h:350
T det() const
Determinant of matrix.
Definition: Mat3.h:481
boost::shared_ptr< const ScaleMap > ConstPtr
Definition: Maps.h:689
static MapBase::Ptr create()
Return a MapBase::Ptr to a new NonlinearFrustumMap.
Definition: Maps.h:2001
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:724
Name type() const
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:957
const Coord & max() const
Definition: Coord.h:281
Mat3d applyIJC(const Mat3d &mat) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1065
MapBase::Ptr preScale(const Vec3d &s) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation to the ...
Definition: Maps.h:2421
bool hasUniformScale() const
Return true if the values have the same magitude (eg. -1, 1, -1 would be a rotation).
Definition: Maps.h:744
boost::shared_ptr< NonlinearFrustumMap > Ptr
Definition: Maps.h:1877
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:754
static Name mapType()
Definition: Maps.h:1029
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:490
OPENVDB_API boost::shared_ptr< SymmetricMap > createSymmetricMap(const Mat3d &m)
Utility methods.
Vec3d applyJacobian(const Vec3d &in, const Vec3d &isloc) const
Return the Jacobian defined at isloc applied to in.
Definition: Maps.h:2092
boost::shared_ptr< ScaleTranslateMap > Ptr
Definition: Maps.h:1177
Mat3 transpose() const
returns transpose of this
Definition: Mat3.h:455
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1418
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1010
MapBase::Ptr preTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a UniformScaleTranslateMap that is the result of prepending translation on t...
Definition: Maps.h:1529
AffineMap::Ptr getAffineMap() const
Return a AffineMap equivalent to this map.
Definition: Maps.h:868
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:348
bool hasUniformScale() const
Return false (by convention true)
Definition: Maps.h:1722
void read(std::istream &is)
read serialization
Definition: Maps.h:1081
static Name mapType()
Definition: Maps.h:738
bool operator==(const TranslationMap &other) const
Definition: Maps.h:1095
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1015
UnitaryMap(const Vec3d &axis, double radians)
Definition: Maps.h:1631
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1852
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:450
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:1086
double determinant(const Vec3d &loc) const
Definition: Maps.h:2300
UniformScaleMap()
Definition: Maps.h:933
CompoundMap< FirstMapType, SecondMapType > MyType
Definition: Maps.h:2569
boost::shared_ptr< AffineMap > Ptr
Definition: Maps.h:327
bool operator!=(const TranslationMap &other) const
Definition: Maps.h:1101
bool isDiagonal() const
Return true if the underylying matrix is diagonal.
Definition: Maps.h:491
static Name mapType()
Definition: Maps.h:958
const Coord & min() const
Definition: Coord.h:280
NonlinearFrustumMap()
Definition: Maps.h:1880
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:1751
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition: Mat4.h:795
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1497
boost::shared_ptr< const MyType > ConstPtr
Definition: Maps.h:2572
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1299
CompoundMap< SymmetricMap, UnitaryAndTranslationMap > FullyDecomposedMap
Definition: Maps.h:72
UniformScaleTranslateMap(double scale, const Vec3d &translate)
Definition: Maps.h:1484
static void registerMap()
Definition: Maps.h:2015
Name type() const
Return NonlinearFrustumMap.
Definition: Maps.h:2022
Vec3d applyInverseJacobian(const Vec3d &in) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:2116
boost::shared_ptr< MyType > Ptr
Definition: Maps.h:2571
static bool isRegistered()
Definition: Maps.h:949
Mat3< T > getMat3() const
Definition: Mat4.h:302
Abstract base class for maps.
Definition: Maps.h:159
void read(std::istream &is)
read serialization
Definition: Maps.h:830
double determinant(const Vec3d &) const
Return the product of the scale values, ignores argument.
Definition: Maps.h:1327
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:762
Vec3d applyInverseJacobian(const Vec3d &in) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:777
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:383
Vec3d applyInverseJacobian(const Vec3d &in) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:1746
double getDepth() const
Return the unscaled frustm depth.
Definition: Maps.h:2340
~UniformScaleTranslateMap()
Definition: Maps.h:1490
static bool isRegistered()
Definition: Maps.h:1019
boost::shared_ptr< UnitaryMap > Ptr
Definition: Maps.h:1623
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1442
MapBase::Ptr preScale(const Vec3d &v) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1816
UnitaryMap(const UnitaryMap &other)
Definition: Maps.h:1682
static void registerMap()
Definition: Maps.h:730
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &isloc) const
Return the Inverse Jacobian defined at isloc of the map applied to in.
Definition: Maps.h:2118
ScaleMap(const ScaleMap &other)
Definition: Maps.h:709
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:636
static void registerMap()
Definition: Maps.h:389
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:783
OPENVDB_API boost::shared_ptr< MapBase > simplify(boost::shared_ptr< AffineMap > affine)
reduces an AffineMap to a ScaleMap or a ScaleTranslateMap when it can
MapBase::Ptr preTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:594
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:848
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1765
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1724
MapBase::Ptr postScale(const Vec3d &s) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:630
OPENVDB_API boost::shared_ptr< FullyDecomposedMap > createFullyDecomposedMap(const Mat4d &m)
General decomposition of a Matrix into a Unitary (e.g. rotation) following a Symmetric (e...
Name type() const
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:1028
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:165
static void registerMap()
Definition: Maps.h:1021
void accumPostShear(Axis axis0, Axis axis1, double shear)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:542
bool isLinear() const
Return true (a TranslationMap is always linear).
Definition: Maps.h:1032
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1763
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:1369
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:2085
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:2079
void setTaper(double t)
set the taper value, the ratio of nearplane width / far plane width
Definition: Maps.h:2334
bool operator!=(const ScaleTranslateMap &other) const
Definition: Maps.h:1388
AffineMap & operator=(const AffineMap &other)
Definition: Maps.h:427
static bool isRegistered()
Definition: Maps.h:728
T & y()
Definition: Vec3.h:98
bool operator==(const ScaleTranslateMap &other) const
Definition: Maps.h:1380
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:2003
const Mat4d & getConstMat4() const
Definition: Maps.h:646
const BBoxd & getBBox() const
Return the bounding box that defines the frustum in pre-image space.
Definition: Maps.h:2345
Name type() const
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:396
AffineMap(const AffineMap &other)
Definition: Maps.h:359
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:370
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1799
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature for the linear second map.
Definition: Maps.h:2221
~TranslationMap()
Definition: Maps.h:1010
void accumPostScale(const Vec3d &v)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:532
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1495
static bool isRegistered()
Definition: Maps.h:2013
const Vec3d & getInvScaleSqr() const
Return the square of the scale. Used to optimize some finite difference calculations.
Definition: Maps.h:814
std::string str() const
string serialization, useful for debugging
Definition: Maps.h:564
double getGamma() const
Definition: Maps.h:2342
Map traits.
Definition: Maps.h:80
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition: Mat4.h:295
Vec3d voxelSize() const
Return the size of a voxel at the center of the near plane.
Definition: Maps.h:2308
UniformScaleTranslateMap(const UniformScaleTranslateMap &other)
Definition: Maps.h:1489
const Vec3d & getTranslation() const
Return the translation vector.
Definition: Maps.h:1079
bool isIdentity() const
Return true if the map is equivalent to an identity.
Definition: Maps.h:2033
bool hasUniformScale() const
Return false (by convention true)
Definition: Maps.h:1035
bool isIdentity() const
Definition: Maps.h:2612
Mat3 inverse(T tolerance=0) const
Definition: Mat3.h:466
CompoundMap(const FirstMapType &f, const SecondMapType &s)
Definition: Maps.h:2577
bool operator==(const UnitaryMap &other) const
Definition: Maps.h:1726
static bool isRegistered()
Definition: Maps.h:1242
void setToRotation(const Quat< T > &q)
Set this matrix to the rotation matrix specified by the quaternion.
Definition: Mat3.h:270
bool operator!=(const ScaleMap &other) const
Definition: Maps.h:865
ScaleTranslateMap(const ScaleMap &scale, const TranslationMap &translate)
Definition: Maps.h:1206
MapBase::Ptr postTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:624
bool isType() const
Return true if this map is of concrete type MapT (e.g., AffineMap).
Definition: Maps.h:174
NonlinearFrustumMap(const BBoxd &bb, double taper, double depth)
Constructor that takes an index-space bounding box to be mapped into a frustum with a given depth and...
Definition: Maps.h:1892
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1303
void accumPreScale(const Vec3d &v)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:507
AffineMap::Ptr inverse() const
Return AffineMap::Ptr to the inverse of this map.
Definition: Maps.h:582
Vec3d voxelSize() const
Returns the lengths of the images of the segments , , .
Definition: Maps.h:1777
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:1737
UnitaryMap(const UnitaryMap &first, const UnitaryMap &second)
Definition: Maps.h:1688
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:834
ScaleMap()
Definition: Maps.h:691
void accumPreShear(Axis axis0, Axis axis1, double shear)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:517
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:772
MapBase::Ptr postTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropiate operation to the l...
Definition: Maps.h:2441
Vec3d voxelSize(const Vec3d &) const
Return .
Definition: Maps.h:1076
void read(std::istream &is)
read serialization
Definition: Maps.h:1781
static const Mat4< double > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:147
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:2052
bool operator!=(const AffineMap &other) const
Definition: Maps.h:425
const Mat3d & getConstJacobianInv() const
Definition: Maps.h:647
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1519
std::map< Name, MapBase::MapFactory > MapDictionary
Definition: Maps.h:289
Vec3d applyInverseJacobian(const Vec3d &in) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:1049
void setTranslation(const Vec3< T > &t)
Definition: Mat4.h:319
Name type() const
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:1251
const Vec3d & getInvScaleSqr() const
Return the square of the scale. Used to optimize some finite difference calculations.
Definition: Maps.h:1342
bool operator!=(const UniformScaleMap &other) const
Definition: Maps.h:963
Creates the composition of two maps, each of which could be a composition. In the case that each comp...
Definition: Maps.h:67
boost::shared_ptr< UniformScaleMap > Ptr
Definition: Maps.h:930
bool operator!=(const MyType &other) const
Definition: Maps.h:2602
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:791
bool operator==(const UniformScaleMap &other) const
Definition: Maps.h:962
const AffineMap & secondMap() const
Return MapBase::Ptr& to the second map.
Definition: Maps.h:2348
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1753
~ScaleMap()
Definition: Maps.h:719
math::BBox< Vec3d > BBoxd
Definition: Types.h:86
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:456
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation to the ...
Definition: Maps.h:2426
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1391
static void registerMap()
Definition: Maps.h:950
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:1174
#define OPENVDB_VERSION_NAME
Definition: version.h:43
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:804
OPENVDB_API boost::shared_ptr< PolarDecomposedMap > createPolarDecomposedMap(const Mat3d &m)
Decomposes a general linear into translation following polar decomposition.
Vec3d applyInverseJacobian(const Vec3d &in) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:452
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:1792
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:385
bool hasUniformScale() const
Return true if the scale values have the same magnitude (eg. -1, 1, -1 would be a rotation)...
Definition: Maps.h:1259
boost::shared_ptr< const UnitaryMap > ConstPtr
Definition: Maps.h:1624
Mat4d getMat4() const
Return the matrix representation of this AffineMap.
Definition: Maps.h:645
Vec3d asVec3d() const
Definition: Coord.h:157
void read(std::istream &is)
read serialization
Definition: Maps.h:2357
AffineMap::Ptr getAffineMap() const
Definition: Maps.h:2331
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UniformScaleMap.
Definition: Maps.h:939
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1822
boost::shared_ptr< const UniformScaleMap > ConstPtr
Definition: Maps.h:931
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:466
AffineMap(const Mat3d &m)
Definition: Maps.h:342
void accumPostTranslation(const Vec3d &v)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:537
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1761
UniformScaleTranslateMap(const UniformScaleMap &scale, const TranslationMap &translate)
Definition: Maps.h:1486
static bool isRegistered()
Definition: Maps.h:387
boost::shared_ptr< MapBase > Ptr
Definition: Maps.h:162
MapBase::Ptr preScale(const Vec3d &s) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:600
Vec3< typename MatType::value_type > getScale(const MatType &mat)
Return a Vec3 representing the lengths of the passed matrix&#39;s upper 3x3&#39;s rows.
Definition: Mat.h:612
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:781
double determinant(const Vec3d &) const
Return the determinant of the Jacobian, ignores argument.
Definition: Maps.h:1768
void setRow(int i, const Vec3< T > &v)
Set ith row to vector v.
Definition: Mat3.h:157
double determinant() const
Return the determinant of the Jacobian.
Definition: Maps.h:1770
MapBase::Ptr preTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1810
ScaleTranslateMap(const Vec3d &scale, const Vec3d &translate)
Definition: Maps.h:1191
Vec3d applyJT(const Vec3d &in, const Vec3d &isloc) const
Definition: Maps.h:2148
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation...
Definition: Maps.h:1130
Vec3d voxelSize() const
Return the absolute values of the scale values.
Definition: Maps.h:1331
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1378
static MapBase::Ptr create()
Return a MapBase::Ptr to a new ScaleMap.
Definition: Maps.h:722
Definition: Maps.h:104
Vec3d voxelSize(const Vec3d &) const
Returns the lengths of the images of the segments , , this is equivalent to the absolute values of t...
Definition: Maps.h:826
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:941
void setDepth(double d)
set the frustum depth: distance between near and far plane = frustm depth * frustm x-width ...
Definition: Maps.h:2338
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropriate operation...
Definition: Maps.h:1155
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Apply the Jacobian of this map to a vector. For a linear map this is equivalent to applying the map e...
Definition: Maps.h:1739
void setSecondMap(const SecondMapType &second)
Definition: Maps.h:2645
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1305
Vec3d applyInverseJacobian(const Vec3d &in) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:1293
MapBase::Ptr postTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropriate operation...
Definition: Maps.h:1148
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to a deep copy of the current AffineMap.
Definition: Maps.h:579
CompoundMap< UnitaryMap, TranslationMap > UnitaryAndTranslationMap
Definition: Maps.h:67
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: Coord.h:383
void write(std::ostream &os) const
write serialization
Definition: Maps.h:2387
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:1766
bool hasSimpleAffine() const
Return true if the second map is a uniform scale, Rotation and translation.
Definition: Maps.h:2354
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1017
bool isLinear() const
Return true (an AffineMap is always linear).
Definition: Maps.h:400
bool hasUniformScale() const
Return false ( test if this is unitary with translation )
Definition: Maps.h:403
MapBase()
Definition: Maps.h:271
Vec3d applyIJT(const Vec3d &d1_is, const Vec3d &ijk) const
Definition: Maps.h:2185
virtual ~MapBase()
Definition: Maps.h:166
std::string Name
Definition: Name.h:44
const Vec3d & getScale() const
Return the scale values that define the map.
Definition: Maps.h:811
Definition: Exceptions.h:39
void read(std::istream &is)
read serialization
Definition: Maps.h:1349
AffineMap::Ptr getAffineMap() const
Definition: Maps.h:2629
static MapBase::Ptr create()
Return a MapBase::Ptr to a new ScaleTranslateMap.
Definition: Maps.h:1232
OPENVDB_API Mat4d approxInverse(const Mat4d &mat)
Returns the left pseudoInverse of the input matrix when the 3x3 part is symmetric otherwise it zeros ...
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:767
NonlinearFrustumMap(const Vec3d &position, const Vec3d &direction, const Vec3d &up, double aspect, double z_near, double depth, Coord::ValueType x_count, Coord::ValueType z_count)
Constructor from a camera frustum.
Definition: Maps.h:1941
double determinant() const
Return the product of the scale values.
Definition: Maps.h:1329
double determinant(const Vec3d &) const
Return the product of the scale values, ignores argument.
Definition: Maps.h:806
static bool isRegistered()
Definition: Maps.h:1504
MatType shear(Axis axis0, Axis axis1, typename MatType::value_type shear)
Set the matrix to a shear along axis0 by a fraction of axis1.
Definition: Mat.h:667
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1699
boost::shared_ptr< const NonlinearFrustumMap > ConstPtr
Definition: Maps.h:1878
CompoundMap(const MyType &other)
Definition: Maps.h:2582
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1286
A specialized Affine transform that uniformaly scales along the principal axis and then translates th...
Definition: Maps.h:1477
const SecondMapType & secondMap() const
Definition: Maps.h:2642
SpectralDecomposedMap SymmetricMap
Definition: Maps.h:71
TranslationMap(const TranslationMap &other)
Definition: Maps.h:1008
boost::shared_ptr< TranslationMap > Ptr
Definition: Maps.h:1002
MapBase::Ptr preTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation to the ...
Definition: Maps.h:2416
Name type() const
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:737
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the linear second map applied to in.
Definition: Maps.h:2090
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1042
MyType & operator=(const MyType &other)
Definition: Maps.h:2604
A specialized Affine transform that scales along the principal axis the scaling is uniform in the thr...
Definition: Maps.h:927
T length() const
Length of the vector.
Definition: Vec3.h:212
T & z()
Definition: Vec3.h:99
Vec3< double > Vec3d
Definition: Vec3.h:643
bool isDiagonal(const MatType &mat)
Determine if a matrix is diagonal.
Definition: Mat.h:876
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation to the ...
Definition: Maps.h:912
static MapBase::Ptr create()
Return a MapBase::Ptr to a new AffineMap.
Definition: Maps.h:381
bool isAffine(const Mat4< T > &m)
Definition: Mat4.h:1336
const Vec3d & getTranslation() const
Returns the translation.
Definition: Maps.h:1339
boost::shared_ptr< const TranslationMap > ConstPtr
Definition: Maps.h:1003
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:2398
Axis
Definition: Math.h:838
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1093
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:415
bool isIdentity() const
Return true if the underlying matrix is approximately an identity.
Definition: Maps.h:489
const Vec3d & getInvTwiceScale() const
Return 1/(2 scale). Used to optimize some finite difference calculations.
Definition: Maps.h:1344
void write(std::ostream &os) const
Definition: Maps.h:2653
ScaleTranslateMap(const ScaleTranslateMap &other)
Definition: Maps.h:1219
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UnitaryMap.
Definition: Maps.h:1695
static Name mapType()
Return UnitaryMap.
Definition: Maps.h:1716
Vec3d voxelSize(const Vec3d &) const
Return the lengths of the images of the segments (0,0,0)-(1,0,0), (0,0,0)-(0,1,0) and (0...
Definition: Maps.h:485
Name readString(std::istream &is)
Definition: Name.h:47
double determinant() const
Return 1.
Definition: Maps.h:1071
MapBase::Ptr postScale(const Vec3d &v) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1846
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1056
boost::shared_ptr< const AffineMap > ConstPtr
Definition: Maps.h:328
void setFirstMap(const FirstMapType &first)
Definition: Maps.h:2644
MapBase::Ptr postScale(const Vec3d &s) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropiate operation to the l...
Definition: Maps.h:2446
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:1040
boost::shared_ptr< const MapBase > ConstPtr
Definition: Maps.h:163
bool hasTranslation(const Mat4< T > &m)
Definition: Mat4.h:1341
bool operator!=(const UnitaryMap &other) const
Definition: Maps.h:1733
static Name mapType()
Return NonlinearFrustumMap.
Definition: Maps.h:2024
void setCol(int j, const Vec3< T > &v)
Set jth column to vector v.
Definition: Mat3.h:175
void read(std::istream &is)
read serialization
Definition: Maps.h:551
~ScaleTranslateMap()
Definition: Maps.h:1229
This map is composed of three steps. First it will take a box of size (Lx X Ly X Lz) defined by a mem...
Definition: Maps.h:1874
UniformScaleTranslateMap()
Definition: Maps.h:1483
const Vec3d & getInvTwiceScale() const
Return 1/(2 scale). Used to optimize some finite difference calculations.
Definition: Maps.h:816
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation to the ...
Definition: Maps.h:889
Vec3d voxelSize(const Vec3d &) const
Definition: Maps.h:1334
static Name mapType()
Definition: Maps.h:1252
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:1297
void write(std::ostream &os) const
write serialization
Definition: Maps.h:839
ScaleMap(const Vec3d &scale)
Definition: Maps.h:695
bool operator==(const AffineMap &other) const
Definition: Maps.h:417
Vec3d voxelSize() const
Return .
Definition: Maps.h:1074
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:943
TranslationMap()
Definition: Maps.h:1006
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1044
static void registerMap()
Definition: Maps.h:1509
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1234
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of under the map.
Definition: Maps.h:1277
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:793
bool operator==(const NonlinearFrustumMap &other) const
Definition: Maps.h:2054
MapBase::Ptr postTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1435
void write(std::ostream &os) const
write serialization
Definition: Maps.h:1083
MapBase::Ptr copy() const
Returns a MapBase::Ptr to a deep copy of *this.
Definition: Maps.h:1697
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:447
Definition: Exceptions.h:84
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:1744
Int32 ValueType
Definition: Coord.h:55
Name type() const
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:1516
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1288
Mat3d applyIJC(const Mat3d &mat, const Vec3d &, const Vec3d &) const
Definition: Maps.h:1066
~UniformScaleMap()
Definition: Maps.h:936
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:960
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian (Identity for TranslationMap) of the map applied to in...
Definition: Maps.h:1063
AffineMap()
Definition: Maps.h:330
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:856
Tolerance for floating-point comparison.
Definition: Math.h:125
static MapBase::Ptr create()
Return a MapBase::Ptr to a new TranslationMap.
Definition: Maps.h:1013
static void registerMap()
Definition: Maps.h:1244
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1741
UnitaryMap(const Mat3d &m)
Definition: Maps.h:1645
MapBase::Ptr preTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation...
Definition: Maps.h:1123
CompoundMap< CompoundMap< UnitaryMap, ScaleMap >, UnitaryMap > SpectralDecomposedMap
Definition: Maps.h:70
void write(std::ostream &os) const
write serialization
Definition: Maps.h:1787
TranslationMap(const Vec3d &t)
Definition: Maps.h:1007
double getTaper() const
Return the taper value.
Definition: Maps.h:2336
MapBase::Ptr inverseMap() const
Not implemented, since there is currently no map type that can represent the inverse of a frustum...
Definition: Maps.h:2008
Definition: Exceptions.h:78
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:445
boost::shared_ptr< const UniformScaleTranslateMap > ConstPtr
Definition: Maps.h:1481
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:1038
UnitaryMap()
default constructor makes an Idenity.
Definition: Maps.h:1627
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian (Identity for TranslationMap) of the map applied to in...
Definition: Maps.h:1060
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:606
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:458
A specialized linear transform that performs a unitary maping i.e. rotation and or reflection...
Definition: Maps.h:1620
ScaleTranslateMap()
Definition: Maps.h:1180
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:1047
boost::shared_ptr< const ScaleTranslateMap > ConstPtr
Definition: Maps.h:1178
Threadsafe singleton object for accessing the map type-name dictionary. Associates a map type-name wi...
Definition: Maps.h:286
UnitaryMap(const Mat4d &m)
Definition: Maps.h:1657
static Name mapType()
Definition: Maps.h:1517
bool isLinear() const
Return true (a ScaleTranslateMap is always linear).
Definition: Maps.h:1255
T * asPointer()
Definition: Vec3.h:106
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:473
boost::shared_ptr< FullyDecomposedMap > createDecomposedMap()
on-demand decomposition of the affine map
Definition: Maps.h:573
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const
Return the Inverse Jacobian of the map applied to in. (i.e. inverse map with out translation) ...
Definition: Maps.h:1291
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
boost::shared_ptr< UniformScaleTranslateMap > Ptr
Definition: Maps.h:1480
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:685
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:726
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:789
const Vec3d & getInvScale() const
Return 1/(scale)
Definition: Maps.h:1346
MapBase::Ptr preTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1407
bool hasUniformScale() const
Return false (by convention false)
Definition: Maps.h:2030
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:594
bool isScale() const
Return true if the map is equivalent to a ScaleMap.
Definition: Maps.h:493
bool operator==(const UniformScaleTranslateMap &other) const
Definition: Maps.h:1521
Mat3d applyIJC(const Mat3d &m) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:470
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UniformScaleTranslateMap.
Definition: Maps.h:1493
bool isLinear() const
Return true (a ScaleMap is always linear).
Definition: Maps.h:741
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:203
Name type() const
Return UnitaryMap.
Definition: Maps.h:1714
bool isDiagonal() const
Definition: Maps.h:2621
Definition: Exceptions.h:82
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:440
static bool isEqualBase(const MapT &self, const MapBase &other)
Definition: Maps.h:274
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the second map applied to in.
Definition: Maps.h:2170
Definition: Math.h:839
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1104
Vec3< T > row(int i) const
Get ith row, e.g. Vec3d v = m.row(1);.
Definition: Mat3.h:168
Name type() const
Definition: Maps.h:2588
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:324
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:1735
bool operator==(const ScaleMap &other) const
Definition: Maps.h:858
bool isValid() const
Definition: Maps.h:2351
CompoundMap< SymmetricMap, UnitaryMap > PolarDecomposedMap
Definition: Maps.h:73
bool isLinear() const
Return false (a NonlinearFrustumMap is never linear).
Definition: Maps.h:2027
static bool isRegistered()
Definition: Maps.h:1704
Vec3d voxelSize(const Vec3d &) const
Method to return the local size of a voxel. When a location is specified as an argument, it is understood to be be in the domain of the map (i.e. index space)
Definition: Maps.h:1778
bool isUnitary(const MatType &m)
Determine if a matrix is unitary (i.e., rotation or reflection).
Definition: Mat.h:863
MapBase::Ptr postTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a UniformScaleTranslateMap that is the result of postfixing translation on t...
Definition: Maps.h:1538
MapBase::Ptr postTranslate(const Vec3d &t) const
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1840
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the linear second map applied to in.
Definition: Maps.h:2175
UniformScaleMap(double scale)
Definition: Maps.h:934
void write(std::ostream &os) const
write serialization
Definition: Maps.h:558
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:442
Mat3d applyIJC(const Mat3d &d2_is, const Vec3d &d1_is, const Vec3d &ijk) const
Definition: Maps.h:2226
CompoundMap()
Definition: Maps.h:2575
UnitaryMap(Axis axis, double radians)
Definition: Maps.h:1638
bool isScaleTranslate() const
Return true if the map is equivalent to a ScaleTranslateMap.
Definition: Maps.h:495
const Vec3d & getInvScale() const
Return 1/(scale)
Definition: Maps.h:818
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:97
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:770
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:252
A specialized linear transform that performs a translation.
Definition: Maps.h:999
void accumPreTranslation(const Vec3d &v)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:512
boost::shared_ptr< ScaleMap > Ptr
Definition: Maps.h:688
AffineMap(const AffineMap &first, const AffineMap &second)
constructor that merges the matrixes for two affine maps
Definition: Maps.h:372
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1313
static Name mapType()
Definition: Maps.h:2589
bool isInvertible(const MatType &m)
Determine if a matrix is invertible.
Definition: Mat.h:843
static void registerMap()
Definition: Maps.h:1706
~NonlinearFrustumMap()
Definition: Maps.h:1999
~AffineMap()
Definition: Maps.h:378
double determinant() const
Return the determinant of the Jacobian of linear second map.
Definition: Maps.h:2296
bool operator!=(const UniformScaleTranslateMap &other) const
Definition: Maps.h:1525
void writeString(std::ostream &os, const Name &name)
Definition: Name.h:58
bool operator!=(const NonlinearFrustumMap &other) const
Definition: Maps.h:2076
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:1324
static Name mapType()
Definition: Maps.h:397
bool isLinear() const
Return true (a UnitaryMap is always linear).
Definition: Maps.h:1719
UniformScaleMap(const UniformScaleMap &other)
Definition: Maps.h:935
~UnitaryMap()
Definition: Maps.h:1693
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:468