OpenVDB  2.3.0
Maps.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2013 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
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/util/Name.h>
42 #include <openvdb/Types.h>
43 #include <boost/shared_ptr.hpp>
44 #include <map>
45 
46 namespace openvdb {
48 namespace OPENVDB_VERSION_NAME {
49 namespace math {
50 
51 
53 
55 
56 class MapBase;
57 class ScaleMap;
58 class TranslationMap;
59 class ScaleTranslateMap;
60 class UniformScaleMap;
61 class UniformScaleTranslateMap;
62 class AffineMap;
63 class UnitaryMap;
64 class NonlinearFrustumMap;
65 
66 template<typename T1, typename T2> class CompoundMap;
67 
73 
74 
76 
78 
79 template<typename T> struct is_linear { static const bool value = false; };
80 template<> struct is_linear<AffineMap> { static const bool value = true; };
81 template<> struct is_linear<ScaleMap> { static const bool value = true; };
82 template<> struct is_linear<UniformScaleMap> { static const bool value = true; };
83 template<> struct is_linear<UnitaryMap> { static const bool value = true; };
84 template<> struct is_linear<TranslationMap> { static const bool value = true; };
85 template<> struct is_linear<ScaleTranslateMap> { static const bool value = true; };
86 template<> struct is_linear<UniformScaleTranslateMap> { static const bool value = true; };
87 
88 template<typename T1, typename T2> struct is_linear<CompoundMap<T1, T2> > {
89  static const bool value = is_linear<T1>::value && is_linear<T2>::value;
90 };
91 
92 
93 template<typename T> struct is_uniform_scale { static const bool value = false; };
94 template<> struct is_uniform_scale<UniformScaleMap> { static const bool value = true; };
95 
96 template<typename T> struct is_uniform_scale_translate { static const bool value = false; };
97 template<> struct is_uniform_scale_translate<TranslationMap> { static const bool value = true; };
99  static const bool value = true;
100 };
101 
102 
103 template<typename T> struct is_scale { static const bool value = false; };
104 template<> struct is_scale<ScaleMap> { static const bool value = true; };
105 
106 template<typename T> struct is_scale_translate { static const bool value = false; };
107 template<> struct is_scale_translate<ScaleTranslateMap> { static const bool value = true; };
108 
109 
110 template<typename T> struct is_uniform_diagonal_jacobian {
112 };
113 
114 template<typename T> struct is_diagonal_jacobian {
115  static const bool value = is_scale<T>::value || is_scale_translate<T>::value;
116 };
117 
118 
120 
122 
125 OPENVDB_API boost::shared_ptr<SymmetricMap> createSymmetricMap(const Mat3d& m);
126 
127 
130 OPENVDB_API boost::shared_ptr<FullyDecomposedMap> createFullyDecomposedMap(const Mat4d& m);
131 
132 
143 OPENVDB_API boost::shared_ptr<PolarDecomposedMap> createPolarDecomposedMap(const Mat3d& m);
144 
145 
147 OPENVDB_API boost::shared_ptr<MapBase> simplify(boost::shared_ptr<AffineMap> affine);
148 
152 
153 
155 
156 
159 {
160 public:
161  typedef boost::shared_ptr<MapBase> Ptr;
162  typedef boost::shared_ptr<const MapBase> ConstPtr;
163  typedef Ptr (*MapFactory)();
164 
165  virtual ~MapBase(){}
166 
167  virtual boost::shared_ptr<AffineMap> getAffineMap() const = 0;
168 
170  virtual Name type() const = 0;
171 
173  template<typename MapT> bool isType() const { return this->type() == MapT::mapType(); }
174 
176  virtual bool isEqual(const MapBase& other) const = 0;
177 
179  virtual bool isLinear() const = 0;
181  virtual bool hasUniformScale() const = 0;
182 
183  virtual Vec3d applyMap(const Vec3d& in) const = 0;
184  virtual Vec3d applyInverseMap(const Vec3d& in) const = 0;
185 
187  virtual Vec3d applyIJT(const Vec3d& in) const = 0;
191  virtual Vec3d applyIJT(const Vec3d& in, const Vec3d& domainPos) const = 0;
193 
194  virtual Mat3d applyIJC(const Mat3d& m) const = 0;
195  virtual Mat3d applyIJC(const Mat3d& m, const Vec3d& v, const Vec3d& domainPos) const = 0;
196 
197 
198  virtual double determinant() const = 0;
199  virtual double determinant(const Vec3d&) const = 0;
200 
201 
203  virtual Vec3d voxelSize() const = 0;
207  virtual Vec3d voxelSize(const Vec3d&) const = 0;
209 
210  virtual void read(std::istream&) = 0;
211  virtual void write(std::ostream&) const = 0;
212 
213  virtual std::string str() const = 0;
214 
215  virtual MapBase::Ptr copy() const = 0;
216 
218  virtual MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const = 0;
220  virtual MapBase::Ptr preTranslate(const Vec3d&) const = 0;
221  virtual MapBase::Ptr preScale(const Vec3d&) const = 0;
222  virtual MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const = 0;
223 
224  virtual MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const = 0;
225  virtual MapBase::Ptr postTranslate(const Vec3d&) const = 0;
226  virtual MapBase::Ptr postScale(const Vec3d&) const = 0;
227  virtual MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const = 0;
229 
231  virtual Vec3d applyJacobian(const Vec3d& in) const = 0;
237  virtual Vec3d applyJacobian(const Vec3d& in, const Vec3d& domainPos) const = 0;
239 
241  virtual Vec3d applyInverseJacobian(const Vec3d& in) const = 0;
247  virtual Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d& domainPos) const = 0;
249 
250 
252  virtual Vec3d applyJT(const Vec3d& in) const = 0;
259  virtual Vec3d applyJT(const Vec3d& in, const Vec3d& domainPos) const = 0;
261 
267  virtual MapBase::Ptr inverseMap() const = 0;
268 
269 protected:
270  MapBase() {}
271 
272  template<typename MapT>
273  static bool isEqualBase(const MapT& self, const MapBase& other)
274  {
275  return other.isType<MapT>() && (self == *static_cast<const MapT*>(&other));
276  }
277 };
278 
279 
281 
282 
286 {
287 public:
288  typedef std::map<Name, MapBase::MapFactory> MapDictionary;
289 
290  static MapRegistry* instance();
291 
293  static MapBase::Ptr createMap(const Name&);
294 
296  static bool isRegistered(const Name&);
297 
299  static void registerMap(const Name&, MapBase::MapFactory);
300 
302  static void unregisterMap(const Name&);
303 
305  static void clear();
306 
307 private:
308  MapRegistry() {}
309 
310  static MapRegistry* staticInstance();
311 
312  static MapRegistry* mInstance;
313 
314  MapDictionary mMap;
315 };
316 
317 
319 
320 
324 {
325 public:
326  typedef boost::shared_ptr<AffineMap> Ptr;
327  typedef boost::shared_ptr<const AffineMap> ConstPtr;
328 
330  mMatrix(Mat4d::identity()),
331  mMatrixInv(Mat4d::identity()),
332  mJacobianInv(Mat3d::identity()),
333  mDeterminant(1),
334  mVoxelSize(Vec3d(1,1,1)),
335  mIsDiagonal(true),
336  mIsIdentity(true)
337  // the default constructor for translation is zero
338  {
339  }
340 
341  AffineMap(const Mat3d& m)
342  {
343  Mat4d mat4(Mat4d::identity());
344  mat4.setMat3(m);
345  mMatrix = mat4;
346  updateAcceleration();
347  }
348 
349  AffineMap(const Mat4d& m): mMatrix(m)
350  {
351  if (!isAffine(m)) {
353  "Tried to initialize an affine transform from a non-affine 4x4 matrix");
354  }
355  updateAcceleration();
356  }
357 
358  AffineMap(const AffineMap& other):
359  MapBase(other),
360  mMatrix(other.mMatrix),
361  mMatrixInv(other.mMatrixInv),
362  mJacobianInv(other.mJacobianInv),
363  mDeterminant(other.mDeterminant),
364  mVoxelSize(other.mVoxelSize),
365  mIsDiagonal(other.mIsDiagonal),
366  mIsIdentity(other.mIsIdentity)
367  {
368  }
369 
371  AffineMap(const AffineMap& first, const AffineMap& second):
372  mMatrix(first.mMatrix * second.mMatrix)
373  {
374  updateAcceleration();
375  }
376 
378 
380  static MapBase::Ptr create() { return MapBase::Ptr(new AffineMap()); }
382  MapBase::Ptr copy() const { return MapBase::Ptr(new AffineMap(*this)); }
383 
384  MapBase::Ptr inverseMap() const { return MapBase::Ptr(new AffineMap(mMatrixInv)); }
385 
386  static bool isRegistered() { return MapRegistry::isRegistered(AffineMap::mapType()); }
387 
388  static void registerMap()
389  {
390  MapRegistry::registerMap(
391  AffineMap::mapType(),
392  AffineMap::create);
393  }
394 
395  Name type() const { return mapType(); }
396  static Name mapType() { return Name("AffineMap"); }
397 
399  bool isLinear() const { return true; }
400 
402  bool hasUniformScale() const
403  {
404  Mat3d mat = mMatrix.getMat3();
405  const double det = mat.det();
406  if (isApproxEqual(det, double(0))) {
407  return false;
408  } else {
409  mat *= (1.f / pow(std::abs(det),1./3.));
410  return isUnitary(mat);
411  }
412  }
413 
414  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
415 
416  bool operator==(const AffineMap& other) const
417  {
418  // the Mat.eq() is approximate
419  if (!mMatrix.eq(other.mMatrix)) { return false; }
420  if (!mMatrixInv.eq(other.mMatrixInv)) { return false; }
421  return true;
422  }
423 
424  bool operator!=(const AffineMap& other) const { return !(*this == other); }
425 
427  {
428  mMatrix = other.mMatrix;
429  mMatrixInv = other.mMatrixInv;
430 
431  mJacobianInv = other.mJacobianInv;
432  mDeterminant = other.mDeterminant;
433  mVoxelSize = other.mVoxelSize;
434  mIsDiagonal = other.mIsDiagonal;
435  mIsIdentity = other.mIsIdentity;
436  return *this;
437  }
439  Vec3d applyMap(const Vec3d& in) const { return in * mMatrix; }
441  Vec3d applyInverseMap(const Vec3d& in) const {return in * mMatrixInv; }
442 
444  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
446  Vec3d applyJacobian(const Vec3d& in) const { return mMatrix.transform3x3(in); }
447 
449  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
451  Vec3d applyInverseJacobian(const Vec3d& in) const { return mMatrixInv.transform3x3(in); }
452 
455  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
457  Vec3d applyJT(const Vec3d& in) const {
458  const double* m = mMatrix.asPointer();
459  return Vec3d( m[ 0] * in[0] + m[ 1] * in[1] + m[ 2] * in[2],
460  m[ 4] * in[0] + m[ 5] * in[1] + m[ 6] * in[2],
461  m[ 8] * in[0] + m[ 9] * in[1] + m[10] * in[2] );
462  }
463 
465  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const { return applyIJT(in); }
467  Vec3d applyIJT(const Vec3d& in) const { return in * mJacobianInv; }
469  Mat3d applyIJC(const Mat3d& m) const {
470  return mJacobianInv.transpose()* m * mJacobianInv;
471  }
472  Mat3d applyIJC(const Mat3d& in, const Vec3d& , const Vec3d& ) const {
473  return applyIJC(in);
474  }
476  double determinant(const Vec3d& ) const { return determinant(); }
478  double determinant() const { return mDeterminant; }
479 
481  Vec3d voxelSize() const { return mVoxelSize; }
484  Vec3d voxelSize(const Vec3d&) const { return voxelSize(); }
486 
488  bool isIdentity() const { return mIsIdentity; }
490  bool isDiagonal() const { return mIsDiagonal; }
492  bool isScale() const { return isDiagonal(); }
494  bool isScaleTranslate() const { return math::isDiagonal(mMatrix.getMat3()); }
495 
496 
497  // Methods that modify the existing affine map
498 
500  void accumPreRotation(Axis axis, double radians)
502  {
503  mMatrix.preRotate(axis, radians);
504  updateAcceleration();
505  }
506  void accumPreScale(const Vec3d& v)
507  {
508  mMatrix.preScale(v);
509  updateAcceleration();
510  }
511  void accumPreTranslation(const Vec3d& v)
512  {
513  mMatrix.preTranslate(v);
514  updateAcceleration();
515  }
516  void accumPreShear(Axis axis0, Axis axis1, double shear)
517  {
518  mMatrix.preShear(axis0, axis1, shear);
519  updateAcceleration();
520  }
522 
523 
525  void accumPostRotation(Axis axis, double radians)
527  {
528  mMatrix.postRotate(axis, radians);
529  updateAcceleration();
530  }
531  void accumPostScale(const Vec3d& v)
532  {
533  mMatrix.postScale(v);
534  updateAcceleration();
535  }
537  {
538  mMatrix.postTranslate(v);
539  updateAcceleration();
540  }
541  void accumPostShear(Axis axis0, Axis axis1, double shear)
542  {
543  mMatrix.postShear(axis0, axis1, shear);
544  updateAcceleration();
545  }
547 
548 
550  void read(std::istream& is)
551  {
552  mMatrix.read(is);
553  updateAcceleration();
554  }
555 
557  void write(std::ostream& os) const
558  {
559  mMatrix.write(os);
560  }
561 
563  std::string str() const
564  {
565  std::ostringstream buffer;
566  buffer << " - mat4:\n" << mMatrix.str() << std::endl;
567  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
568  return buffer.str();
569  }
570 
572  boost::shared_ptr<FullyDecomposedMap> createDecomposedMap()
573  {
574  return createFullyDecomposedMap(mMatrix);
575  }
576 
578  AffineMap::Ptr getAffineMap() const { return AffineMap::Ptr(new AffineMap(*this)); }
579 
581  AffineMap::Ptr inverse() const { return AffineMap::Ptr(new AffineMap(mMatrixInv)); }
582 
583 
585  MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const
588  {
589  AffineMap::Ptr affineMap = getAffineMap();
590  affineMap->accumPreRotation(axis, radians);
591  return simplify(affineMap);
592  }
594  {
595  AffineMap::Ptr affineMap = getAffineMap();
596  affineMap->accumPreTranslation(t);
597  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
598  }
599  MapBase::Ptr preScale(const Vec3d& s) const
600  {
601  AffineMap::Ptr affineMap = getAffineMap();
602  affineMap->accumPreScale(s);
603  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
604  }
605  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
606  {
607  AffineMap::Ptr affineMap = getAffineMap();
608  affineMap->accumPreShear(axis0, axis1, shear);
609  return simplify(affineMap);
610  }
612 
613 
615  MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const
618  {
619  AffineMap::Ptr affineMap = getAffineMap();
620  affineMap->accumPostRotation(axis, radians);
621  return simplify(affineMap);
622  }
624  {
625  AffineMap::Ptr affineMap = getAffineMap();
626  affineMap->accumPostTranslation(t);
627  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
628  }
629  MapBase::Ptr postScale(const Vec3d& s) const
630  {
631  AffineMap::Ptr affineMap = getAffineMap();
632  affineMap->accumPostScale(s);
633  return boost::static_pointer_cast<MapBase, AffineMap>(affineMap);
634  }
635  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
636  {
637  AffineMap::Ptr affineMap = getAffineMap();
638  affineMap->accumPostShear(axis0, axis1, shear);
639  return simplify(affineMap);
640  }
642 
644  Mat4d getMat4() const { return mMatrix;}
645  const Mat4d& getConstMat4() const {return mMatrix;}
646  const Mat3d& getConstJacobianInv() const {return mJacobianInv;}
647 
648 private:
649  void updateAcceleration() {
650  Mat3d mat3 = mMatrix.getMat3();
651  mDeterminant = mat3.det();
652 
653  if (std::abs(mDeterminant) < (3.0 * math::Tolerance<double>::value())) {
655  "Tried to initialize an affine transform from a nearly singular matrix");
656  }
657  mMatrixInv = mMatrix.inverse();
658  mJacobianInv = mat3.inverse().transpose();
659  mIsDiagonal = math::isDiagonal(mMatrix);
660  mIsIdentity = math::isIdentity(mMatrix);
661  Vec3d pos = applyMap(Vec3d(0,0,0));
662  mVoxelSize(0) = (applyMap(Vec3d(1,0,0)) - pos).length();
663  mVoxelSize(1) = (applyMap(Vec3d(0,1,0)) - pos).length();
664  mVoxelSize(2) = (applyMap(Vec3d(0,0,1)) - pos).length();
665  }
666 
667  // the underlying matrix
668  Mat4d mMatrix;
669 
670  // stored for acceleration
671  Mat4d mMatrixInv;
672  Mat3d mJacobianInv;
673  double mDeterminant;
674  Vec3d mVoxelSize;
675  bool mIsDiagonal, mIsIdentity;
676 }; // class AffineMap
677 
678 
680 
681 
685 {
686 public:
687  typedef boost::shared_ptr<ScaleMap> Ptr;
688  typedef boost::shared_ptr<const ScaleMap> ConstPtr;
689 
690  ScaleMap(): MapBase(), mScaleValues(Vec3d(1,1,1)), mVoxelSize(Vec3d(1,1,1)),
691  mScaleValuesInverse(Vec3d(1,1,1)),
692  mInvScaleSqr(1,1,1), mInvTwiceScale(0.5,0.5,0.5){}
693 
695  MapBase(),
696  mScaleValues(scale),
697  mVoxelSize(Vec3d(std::abs(scale(0)),std::abs(scale(1)), std::abs(scale(2))))
698  {
699  double determinant = scale[0]* scale[1] * scale[2];
700  if (std::abs(determinant) < 3.0 * math::Tolerance<double>::value()) {
701  OPENVDB_THROW(ArithmeticError, "Non-zero scale values required");
702  }
703  mScaleValuesInverse = 1.0 / mScaleValues;
704  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
705  mInvTwiceScale = mScaleValuesInverse / 2;
706  }
707 
708  ScaleMap(const ScaleMap& other):
709  MapBase(),
710  mScaleValues(other.mScaleValues),
711  mVoxelSize(other.mVoxelSize),
712  mScaleValuesInverse(other.mScaleValuesInverse),
713  mInvScaleSqr(other.mInvScaleSqr),
714  mInvTwiceScale(other.mInvTwiceScale)
715  {
716  }
717 
719 
721  static MapBase::Ptr create() { return MapBase::Ptr(new ScaleMap()); }
723  MapBase::Ptr copy() const { return MapBase::Ptr(new ScaleMap(*this)); }
724 
725  MapBase::Ptr inverseMap() const { return MapBase::Ptr(new ScaleMap(mScaleValuesInverse)); }
726 
727  static bool isRegistered() { return MapRegistry::isRegistered(ScaleMap::mapType()); }
728 
729  static void registerMap()
730  {
731  MapRegistry::registerMap(
732  ScaleMap::mapType(),
733  ScaleMap::create);
734  }
735 
736  Name type() const { return mapType(); }
737  static Name mapType() { return Name("ScaleMap"); }
738 
740  bool isLinear() const { return true; }
741 
743  bool hasUniformScale() const
744  {
745  bool value = isApproxEqual(
746  std::abs(mScaleValues.x()), std::abs(mScaleValues.y()), double(5e-7));
747  value = value && isApproxEqual(
748  std::abs(mScaleValues.x()), std::abs(mScaleValues.z()), double(5e-7));
749  return value;
750  }
751 
753  Vec3d applyMap(const Vec3d& in) const
754  {
755  return Vec3d(
756  in.x() * mScaleValues.x(),
757  in.y() * mScaleValues.y(),
758  in.z() * mScaleValues.z());
759  }
761  Vec3d applyInverseMap(const Vec3d& in) const
762  {
763  return Vec3d(
764  in.x() * mScaleValuesInverse.x(),
765  in.y() * mScaleValuesInverse.y(),
766  in.z() * mScaleValuesInverse.z());
767  }
769  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
771  Vec3d applyJacobian(const Vec3d& in) const { return applyMap(in); }
772 
774  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
776  Vec3d applyInverseJacobian(const Vec3d& in) const { return applyInverseMap(in); }
777 
780  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
782  Vec3d applyJT(const Vec3d& in) const { return applyMap(in); }
783 
784 
785 
788  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const { return applyIJT(in);}
790  Vec3d applyIJT(const Vec3d& in) const { return applyInverseMap(in); }
792  Mat3d applyIJC(const Mat3d& in) const
793  {
794  Mat3d tmp;
795  for (int i = 0; i < 3; i++) {
796  tmp.setRow(i, in.row(i) * mScaleValuesInverse(i));
797  }
798  for (int i = 0; i < 3; i++) {
799  tmp.setCol(i, tmp.col(i) * mScaleValuesInverse(i));
800  }
801  return tmp;
802  }
803  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d&) const { return applyIJC(in); }
805  double determinant(const Vec3d&) const { return determinant(); }
807  double determinant() const { return mScaleValues.x() * mScaleValues.y() * mScaleValues.z(); }
808 
810  const Vec3d& getScale() const {return mScaleValues;}
811 
813  const Vec3d& getInvScaleSqr() const { return mInvScaleSqr; }
815  const Vec3d& getInvTwiceScale() const { return mInvTwiceScale; }
817  const Vec3d& getInvScale() const { return mScaleValuesInverse; }
818 
820  Vec3d voxelSize() const { return mVoxelSize; }
825  Vec3d voxelSize(const Vec3d&) const { return voxelSize(); }
827 
829  void read(std::istream& is)
830  {
831  mScaleValues.read(is);
832  mVoxelSize.read(is);
833  mScaleValuesInverse.read(is);
834  mInvScaleSqr.read(is);
835  mInvTwiceScale.read(is);
836  }
838  void write(std::ostream& os) const
839  {
840  mScaleValues.write(os);
841  mVoxelSize.write(os);
842  mScaleValuesInverse.write(os);
843  mInvScaleSqr.write(os);
844  mInvTwiceScale.write(os);
845  }
847  std::string str() const
848  {
849  std::ostringstream buffer;
850  buffer << " - scale: " << mScaleValues << std::endl;
851  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
852  return buffer.str();
853  }
854 
855  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
856 
857  bool operator==(const ScaleMap& other) const
858  {
859  // ::eq() uses a tolerance
860  if (!mScaleValues.eq(other.mScaleValues)) { return false; }
861  return true;
862  }
863 
864  bool operator!=(const ScaleMap& other) const { return !(*this == other); }
865 
868  {
869  return AffineMap::Ptr(new AffineMap(math::scale<Mat4d>(mScaleValues)));
870  }
871 
872 
873 
875  MapBase::Ptr preRotate(double radians, Axis axis) const
878  {
879  AffineMap::Ptr affineMap = getAffineMap();
880  affineMap->accumPreRotation(axis, radians);
881  return simplify(affineMap);
882  }
883 
884  MapBase::Ptr preTranslate(const Vec3d& tr) const;
885 
886  MapBase::Ptr preScale(const Vec3d& v) const;
887 
888  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
889  {
890  AffineMap::Ptr affineMap = getAffineMap();
891  affineMap->accumPreShear(axis0, axis1, shear);
892  return simplify(affineMap);
893  }
895 
896 
898  MapBase::Ptr postRotate(double radians, Axis axis) const
901  {
902  AffineMap::Ptr affineMap = getAffineMap();
903  affineMap->accumPostRotation(axis, radians);
904  return simplify(affineMap);
905  }
906 
907  MapBase::Ptr postTranslate(const Vec3d& tr) const;
908 
909  MapBase::Ptr postScale(const Vec3d& v) const;
910 
911  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
912  {
913  AffineMap::Ptr affineMap = getAffineMap();
914  affineMap->accumPostShear(axis0, axis1, shear);
915  return simplify(affineMap);
916  }
918 
919 private:
920  Vec3d mScaleValues, mVoxelSize, mScaleValuesInverse, mInvScaleSqr, mInvTwiceScale;
921 }; // class ScaleMap
922 
923 
927 {
928 public:
929  typedef boost::shared_ptr<UniformScaleMap> Ptr;
930  typedef boost::shared_ptr<const UniformScaleMap> ConstPtr;
931 
933  UniformScaleMap(double scale): ScaleMap(Vec3d(scale, scale, scale)) {}
934  UniformScaleMap(const UniformScaleMap& other): ScaleMap(other) {}
936 
938  static MapBase::Ptr create() { return MapBase::Ptr(new UniformScaleMap()); }
940  MapBase::Ptr copy() const { return MapBase::Ptr(new UniformScaleMap(*this)); }
941 
943  {
944  const Vec3d& invScale = getInvScale();
945  return MapBase::Ptr(new UniformScaleMap( invScale[0]));
946  }
947 
948  static bool isRegistered() { return MapRegistry::isRegistered(UniformScaleMap::mapType()); }
949  static void registerMap()
950  {
951  MapRegistry::registerMap(
952  UniformScaleMap::mapType(),
953  UniformScaleMap::create);
954  }
955 
956  Name type() const { return mapType(); }
957  static Name mapType() { return Name("UniformScaleMap"); }
958 
959  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
960 
961  bool operator==(const UniformScaleMap& other) const { return ScaleMap::operator==(other); }
962  bool operator!=(const UniformScaleMap& other) const { return !(*this == other); }
963 
966  MapBase::Ptr preTranslate(const Vec3d& tr) const;
967 
970  MapBase::Ptr postTranslate(const Vec3d& tr) const;
971 
972 }; // class UniformScaleMap
973 
974 
976 
977 
978 inline MapBase::Ptr
979 ScaleMap::preScale(const Vec3d& v) const
980 {
981  const Vec3d new_scale(v * mScaleValues);
982  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
983  return MapBase::Ptr(new UniformScaleMap(new_scale[0]));
984  } else {
985  return MapBase::Ptr(new ScaleMap(new_scale));
986  }
987 }
988 
989 
990 inline MapBase::Ptr
991 ScaleMap::postScale(const Vec3d& v) const
992 { // pre-post Scale are the same for a scale map
993  return preScale(v);
994 }
995 
996 
999 {
1000 public:
1001  typedef boost::shared_ptr<TranslationMap> Ptr;
1002  typedef boost::shared_ptr<const TranslationMap> ConstPtr;
1003 
1004  // default constructor is a translation by zero.
1005  TranslationMap(): MapBase(), mTranslation(Vec3d(0,0,0)) {}
1006  TranslationMap(const Vec3d& t): MapBase(), mTranslation(t) {}
1007  TranslationMap(const TranslationMap& other): MapBase(), mTranslation(other.mTranslation) {}
1008 
1010 
1012  static MapBase::Ptr create() { return MapBase::Ptr(new TranslationMap()); }
1014  MapBase::Ptr copy() const { return MapBase::Ptr(new TranslationMap(*this)); }
1015 
1016  MapBase::Ptr inverseMap() const { return MapBase::Ptr(new TranslationMap(-mTranslation)); }
1017 
1018  static bool isRegistered() { return MapRegistry::isRegistered(TranslationMap::mapType()); }
1019 
1020  static void registerMap()
1021  {
1022  MapRegistry::registerMap(
1023  TranslationMap::mapType(),
1024  TranslationMap::create);
1025  }
1026 
1027  Name type() const { return mapType(); }
1028  static Name mapType() { return Name("TranslationMap"); }
1029 
1031  bool isLinear() const { return true; }
1032 
1034  bool hasUniformScale() const { return true; }
1035 
1037  Vec3d applyMap(const Vec3d& in) const { return in + mTranslation; }
1039  Vec3d applyInverseMap(const Vec3d& in) const { return in - mTranslation; }
1041  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
1043  Vec3d applyJacobian(const Vec3d& in) const { return in; }
1044 
1046  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
1048  Vec3d applyInverseJacobian(const Vec3d& in) const { return in; }
1049 
1050 
1053  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
1055  Vec3d applyJT(const Vec3d& in) const { return in; }
1056 
1059  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const { return applyIJT(in);}
1062  Vec3d applyIJT(const Vec3d& in) const {return in;}
1064  Mat3d applyIJC(const Mat3d& mat) const {return mat;}
1065  Mat3d applyIJC(const Mat3d& mat, const Vec3d&, const Vec3d&) const { return applyIJC(mat); }
1066 
1068  double determinant(const Vec3d& ) const { return determinant(); }
1070  double determinant() const { return 1.0; }
1071 
1073  Vec3d voxelSize() const { return Vec3d(1,1,1);}
1075  Vec3d voxelSize(const Vec3d&) const { return voxelSize();}
1076 
1078  const Vec3d& getTranslation() const { return mTranslation; }
1080  void read(std::istream& is) { mTranslation.read(is); }
1082  void write(std::ostream& os) const { mTranslation.write(os); }
1083 
1085  std::string str() const
1086  {
1087  std::ostringstream buffer;
1088  buffer << " - translation: " << mTranslation << std::endl;
1089  return buffer.str();
1090  }
1091 
1092  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1093 
1094  bool operator==(const TranslationMap& other) const
1095  {
1096  // ::eq() uses a tolerance
1097  return mTranslation.eq(other.mTranslation);
1098  }
1099 
1100  bool operator!=(const TranslationMap& other) const { return !(*this == other); }
1101 
1104  {
1105  Mat4d matrix(Mat4d::identity());
1106  matrix.setTranslation(mTranslation);
1107 
1108  AffineMap::Ptr affineMap(new AffineMap(matrix));
1109  return affineMap;
1110  }
1111 
1113  MapBase::Ptr preRotate(double radians, Axis axis) const
1116  {
1117  AffineMap::Ptr affineMap = getAffineMap();
1118  affineMap->accumPreRotation(axis, radians);
1119  return simplify(affineMap);
1120 
1121  }
1123  {
1124  return MapBase::Ptr(new TranslationMap(t + mTranslation));
1125  }
1126 
1127  MapBase::Ptr preScale(const Vec3d& v) const;
1128 
1129  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
1130  {
1131  AffineMap::Ptr affineMap = getAffineMap();
1132  affineMap->accumPreShear(axis0, axis1, shear);
1133  return simplify(affineMap);
1134  }
1136 
1138  MapBase::Ptr postRotate(double radians, Axis axis) const
1141  {
1142  AffineMap::Ptr affineMap = getAffineMap();
1143  affineMap->accumPostRotation(axis, radians);
1144  return simplify(affineMap);
1145 
1146  }
1148  { // post and pre are the same for this
1149  return MapBase::Ptr(new TranslationMap(t + mTranslation));
1150  }
1151 
1152  MapBase::Ptr postScale(const Vec3d& v) const;
1153 
1154  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
1155  {
1156  AffineMap::Ptr affineMap = getAffineMap();
1157  affineMap->accumPostShear(axis0, axis1, shear);
1158  return simplify(affineMap);
1159  }
1161 
1162 private:
1163  Vec3d mTranslation;
1164 }; // class TranslationMap
1165 
1166 
1168 
1169 
1174 {
1175 public:
1176  typedef boost::shared_ptr<ScaleTranslateMap> Ptr;
1177  typedef boost::shared_ptr<const ScaleTranslateMap> ConstPtr;
1178 
1180  MapBase(),
1181  mTranslation(Vec3d(0,0,0)),
1182  mScaleValues(Vec3d(1,1,1)),
1183  mVoxelSize(Vec3d(1,1,1)),
1184  mScaleValuesInverse(Vec3d(1,1,1)),
1185  mInvScaleSqr(1,1,1),
1186  mInvTwiceScale(0.5,0.5,0.5)
1187  {
1188  }
1189 
1190  ScaleTranslateMap(const Vec3d& scale, const Vec3d& translate):
1191  MapBase(),
1192  mTranslation(translate),
1193  mScaleValues(scale),
1194  mVoxelSize(std::abs(scale(0)), std::abs(scale(1)), std::abs(scale(2)))
1195  {
1196  const double determinant = scale[0]* scale[1] * scale[2];
1197  if (std::abs(determinant) < 3.0 * math::Tolerance<double>::value()) {
1198  OPENVDB_THROW(ArithmeticError, "Non-zero scale values required");
1199  }
1200  mScaleValuesInverse = 1.0 / mScaleValues;
1201  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
1202  mInvTwiceScale = mScaleValuesInverse / 2;
1203  }
1204 
1205  ScaleTranslateMap(const ScaleMap& scale, const TranslationMap& translate):
1206  MapBase(),
1207  mTranslation(translate.getTranslation()),
1208  mScaleValues(scale.getScale()),
1209  mVoxelSize(std::abs(mScaleValues(0)),
1210  std::abs(mScaleValues(1)),
1211  std::abs(mScaleValues(2))),
1212  mScaleValuesInverse(1.0 / scale.getScale())
1213  {
1214  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
1215  mInvTwiceScale = mScaleValuesInverse / 2;
1216  }
1217 
1219  MapBase(),
1220  mTranslation(other.mTranslation),
1221  mScaleValues(other.mScaleValues),
1222  mVoxelSize(other.mVoxelSize),
1223  mScaleValuesInverse(other.mScaleValuesInverse),
1224  mInvScaleSqr(other.mInvScaleSqr),
1225  mInvTwiceScale(other.mInvTwiceScale)
1226  {}
1227 
1229 
1233  MapBase::Ptr copy() const { return MapBase::Ptr(new ScaleTranslateMap(*this)); }
1234 
1236  {
1237  return MapBase::Ptr(new ScaleTranslateMap(
1238  mScaleValuesInverse, -mScaleValuesInverse * mTranslation));
1239  }
1240 
1241  static bool isRegistered() { return MapRegistry::isRegistered(ScaleTranslateMap::mapType()); }
1242 
1243  static void registerMap()
1244  {
1245  MapRegistry::registerMap(
1246  ScaleTranslateMap::mapType(),
1247  ScaleTranslateMap::create);
1248  }
1249 
1250  Name type() const { return mapType(); }
1251  static Name mapType() { return Name("ScaleTranslateMap"); }
1252 
1254  bool isLinear() const { return true; }
1255 
1258  bool hasUniformScale() const
1259  {
1260  bool value = isApproxEqual(
1261  std::abs(mScaleValues.x()), std::abs(mScaleValues.y()), double(5e-7));
1262  value = value && isApproxEqual(
1263  std::abs(mScaleValues.x()), std::abs(mScaleValues.z()), double(5e-7));
1264  return value;
1265  }
1266 
1268  Vec3d applyMap(const Vec3d& in) const
1269  {
1270  return Vec3d(
1271  in.x() * mScaleValues.x() + mTranslation.x(),
1272  in.y() * mScaleValues.y() + mTranslation.y(),
1273  in.z() * mScaleValues.z() + mTranslation.z());
1274  }
1276  Vec3d applyInverseMap(const Vec3d& in) const
1277  {
1278  return Vec3d(
1279  (in.x() - mTranslation.x() ) * mScaleValuesInverse.x(),
1280  (in.y() - mTranslation.y() ) * mScaleValuesInverse.y(),
1281  (in.z() - mTranslation.z() ) * mScaleValuesInverse.z());
1282  }
1283 
1285  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
1287  Vec3d applyJacobian(const Vec3d& in) const { return in * mScaleValues; }
1288 
1290  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
1292  Vec3d applyInverseJacobian(const Vec3d& in) const { return in * mScaleValuesInverse; }
1293 
1296  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
1298  Vec3d applyJT(const Vec3d& in) const { return applyJacobian(in); }
1299 
1302  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const { return applyIJT(in);}
1304  Vec3d applyIJT(const Vec3d& in) const
1305  {
1306  return Vec3d(
1307  in.x() * mScaleValuesInverse.x(),
1308  in.y() * mScaleValuesInverse.y(),
1309  in.z() * mScaleValuesInverse.z());
1310  }
1312  Mat3d applyIJC(const Mat3d& in) const
1313  {
1314  Mat3d tmp;
1315  for (int i=0; i<3; i++){
1316  tmp.setRow(i, in.row(i)*mScaleValuesInverse(i));
1317  }
1318  for (int i=0; i<3; i++){
1319  tmp.setCol(i, tmp.col(i)*mScaleValuesInverse(i));
1320  }
1321  return tmp;
1322  }
1323  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d& ) const { return applyIJC(in); }
1324 
1326  double determinant(const Vec3d& ) const { return determinant(); }
1328  double determinant() const { return mScaleValues.x()*mScaleValues.y()*mScaleValues.z(); }
1330  Vec3d voxelSize() const { return mVoxelSize;}
1333  Vec3d voxelSize(const Vec3d&) const { return voxelSize();}
1334 
1336  const Vec3d& getScale() const { return mScaleValues; }
1338  const Vec3d& getTranslation() const { return mTranslation; }
1339 
1341  const Vec3d& getInvScaleSqr() const {return mInvScaleSqr;}
1343  const Vec3d& getInvTwiceScale() const {return mInvTwiceScale;}
1345  const Vec3d& getInvScale() const {return mScaleValuesInverse; }
1346 
1348  void read(std::istream& is)
1349  {
1350  mTranslation.read(is);
1351  mScaleValues.read(is);
1352  mVoxelSize.read(is);
1353  mScaleValuesInverse.read(is);
1354  mInvScaleSqr.read(is);
1355  mInvTwiceScale.read(is);
1356  }
1358  void write(std::ostream& os) const
1359  {
1360  mTranslation.write(os);
1361  mScaleValues.write(os);
1362  mVoxelSize.write(os);
1363  mScaleValuesInverse.write(os);
1364  mInvScaleSqr.write(os);
1365  mInvTwiceScale.write(os);
1366  }
1368  std::string str() const
1369  {
1370  std::ostringstream buffer;
1371  buffer << " - translation: " << mTranslation << std::endl;
1372  buffer << " - scale: " << mScaleValues << std::endl;
1373  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
1374  return buffer.str();
1375  }
1376 
1377  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1378 
1379  bool operator==(const ScaleTranslateMap& other) const
1380  {
1381  // ::eq() uses a tolerance
1382  if (!mScaleValues.eq(other.mScaleValues)) { return false; }
1383  if (!mTranslation.eq(other.mTranslation)) { return false; }
1384  return true;
1385  }
1386 
1387  bool operator!=(const ScaleTranslateMap& other) const { return !(*this == other); }
1388 
1391  {
1392  AffineMap::Ptr affineMap(new AffineMap(math::scale<Mat4d>(mScaleValues)));
1393  affineMap->accumPostTranslation(mTranslation);
1394  return affineMap;
1395  }
1396 
1398  MapBase::Ptr preRotate(double radians, Axis axis) const
1401  {
1402  AffineMap::Ptr affineMap = getAffineMap();
1403  affineMap->accumPreRotation(axis, radians);
1404  return simplify(affineMap);
1405  }
1407  {
1408  const Vec3d& s = mScaleValues;
1409  const Vec3d scaled_trans( t.x() * s.x(),
1410  t.y() * s.y(),
1411  t.z() * s.z() );
1412  return MapBase::Ptr( new ScaleTranslateMap(mScaleValues, mTranslation + scaled_trans));
1413  }
1414 
1415  MapBase::Ptr preScale(const Vec3d& v) const;
1416 
1417  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
1418  {
1419  AffineMap::Ptr affineMap = getAffineMap();
1420  affineMap->accumPreShear(axis0, axis1, shear);
1421  return simplify(affineMap);
1422  }
1424 
1426  MapBase::Ptr postRotate(double radians, Axis axis) const
1429  {
1430  AffineMap::Ptr affineMap = getAffineMap();
1431  affineMap->accumPostRotation(axis, radians);
1432  return simplify(affineMap);
1433  }
1435  {
1436  return MapBase::Ptr( new ScaleTranslateMap(mScaleValues, mTranslation + t));
1437  }
1438 
1439  MapBase::Ptr postScale(const Vec3d& v) const;
1440 
1441  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
1442  {
1443  AffineMap::Ptr affineMap = getAffineMap();
1444  affineMap->accumPostShear(axis0, axis1, shear);
1445  return simplify(affineMap);
1446  }
1448 
1449 private:
1450  Vec3d mTranslation, mScaleValues, mVoxelSize, mScaleValuesInverse,
1451  mInvScaleSqr, mInvTwiceScale;
1452 }; // class ScaleTanslateMap
1453 
1454 
1455 inline MapBase::Ptr
1456 ScaleMap::postTranslate(const Vec3d& t) const
1457 {
1458  return MapBase::Ptr(new ScaleTranslateMap(mScaleValues, t));
1459 }
1460 
1461 
1462 inline MapBase::Ptr
1463 ScaleMap::preTranslate(const Vec3d& t) const
1464 {
1465 
1466  const Vec3d& s = mScaleValues;
1467  const Vec3d scaled_trans( t.x() * s.x(),
1468  t.y() * s.y(),
1469  t.z() * s.z() );
1470  return MapBase::Ptr(new ScaleTranslateMap(mScaleValues, scaled_trans));
1471 }
1472 
1473 
1477 {
1478 public:
1479  typedef boost::shared_ptr<UniformScaleTranslateMap> Ptr;
1480  typedef boost::shared_ptr<const UniformScaleTranslateMap> ConstPtr;
1481 
1483  UniformScaleTranslateMap(double scale, const Vec3d& translate):
1484  ScaleTranslateMap(Vec3d(scale,scale,scale), translate) {}
1486  ScaleTranslateMap(scale.getScale(), translate.getTranslation()) {}
1487 
1490 
1494  MapBase::Ptr copy() const { return MapBase::Ptr(new UniformScaleTranslateMap(*this)); }
1495 
1497  {
1498  const Vec3d& scaleInv = getInvScale();
1499  const Vec3d& trans = getTranslation();
1500  return MapBase::Ptr(new UniformScaleTranslateMap(scaleInv[0], -scaleInv[0] * trans));
1501  }
1502 
1503  static bool isRegistered()
1504  {
1505  return MapRegistry::isRegistered(UniformScaleTranslateMap::mapType());
1506  }
1507 
1508  static void registerMap()
1509  {
1510  MapRegistry::registerMap(
1511  UniformScaleTranslateMap::mapType(),
1512  UniformScaleTranslateMap::create);
1513  }
1514 
1515  Name type() const { return mapType(); }
1516  static Name mapType() { return Name("UniformScaleTranslateMap"); }
1517 
1518  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1519 
1520  bool operator==(const UniformScaleTranslateMap& other) const
1521  {
1522  return ScaleTranslateMap::operator==(other);
1523  }
1524  bool operator!=(const UniformScaleTranslateMap& other) const { return !(*this == other); }
1525 
1529  {
1530  const double scale = this->getScale().x();
1531  const Vec3d new_trans = this->getTranslation() + scale * t;
1532  return MapBase::Ptr( new UniformScaleTranslateMap(scale, new_trans));
1533  }
1534 
1538  {
1539  const double scale = this->getScale().x();
1540  return MapBase::Ptr( new UniformScaleTranslateMap(scale, this->getTranslation() + t));
1541  }
1542 }; // class UniformScaleTanslateMap
1543 
1544 
1545 inline MapBase::Ptr
1546 UniformScaleMap::postTranslate(const Vec3d& t) const
1547 {
1548  const double scale = this->getScale().x();
1549  return MapBase::Ptr(new UniformScaleTranslateMap(scale, t));
1550 }
1551 
1552 
1553 inline MapBase::Ptr
1554 UniformScaleMap::preTranslate(const Vec3d& t) const
1555 {
1556  const double scale = this->getScale().x();
1557  return MapBase::Ptr(new UniformScaleTranslateMap(scale, scale*t));
1558 }
1559 
1560 
1561 inline MapBase::Ptr
1562 TranslationMap::preScale(const Vec3d& v) const
1563 {
1564  if (isApproxEqual(v[0],v[1]) && isApproxEqual(v[0],v[2])) {
1565  return MapBase::Ptr(new UniformScaleTranslateMap(v[0], mTranslation));
1566  } else {
1567  return MapBase::Ptr(new ScaleTranslateMap(v, mTranslation));
1568  }
1569 }
1570 
1571 
1572 inline MapBase::Ptr
1573 TranslationMap::postScale(const Vec3d& v) const
1574 {
1575  if (isApproxEqual(v[0],v[1]) && isApproxEqual(v[0],v[2])) {
1576  return MapBase::Ptr(new UniformScaleTranslateMap(v[0], v[0]*mTranslation));
1577  } else {
1578  const Vec3d trans(mTranslation.x()*v.x(),
1579  mTranslation.y()*v.y(),
1580  mTranslation.z()*v.z());
1581  return MapBase::Ptr(new ScaleTranslateMap(v, trans));
1582  }
1583 }
1584 
1585 
1586 inline MapBase::Ptr
1587 ScaleTranslateMap::preScale(const Vec3d& v) const
1588 {
1589  const Vec3d new_scale( v * mScaleValues );
1590  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
1591  return MapBase::Ptr( new UniformScaleTranslateMap(new_scale[0], mTranslation));
1592  } else {
1593  return MapBase::Ptr( new ScaleTranslateMap(new_scale, mTranslation));
1594  }
1595 }
1596 
1597 
1598 inline MapBase::Ptr
1599 ScaleTranslateMap::postScale(const Vec3d& v) const
1600 {
1601  const Vec3d new_scale( v * mScaleValues );
1602  const Vec3d new_trans( mTranslation.x()*v.x(),
1603  mTranslation.y()*v.y(),
1604  mTranslation.z()*v.z() );
1605 
1606  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
1607  return MapBase::Ptr( new UniformScaleTranslateMap(new_scale[0], new_trans));
1608  } else {
1609  return MapBase::Ptr( new ScaleTranslateMap(new_scale, new_trans));
1610  }
1611 }
1612 
1613 
1615 
1616 
1620 {
1621 public:
1622  typedef boost::shared_ptr<UnitaryMap> Ptr;
1623  typedef boost::shared_ptr<const UnitaryMap> ConstPtr;
1624 
1626  UnitaryMap(): mAffineMap(Mat4d::identity())
1627  {
1628  }
1629 
1630  UnitaryMap(const Vec3d& axis, double radians)
1631  {
1632  Mat3d matrix;
1633  matrix.setToRotation(axis, radians);
1634  mAffineMap = AffineMap(matrix);
1635  }
1636 
1637  UnitaryMap(Axis axis, double radians)
1638  {
1639  Mat4d matrix;
1640  matrix.setToRotation(axis, radians);
1641  mAffineMap = AffineMap(matrix);
1642  }
1643 
1644  UnitaryMap(const Mat3d& m)
1645  {
1646  // test that the mat3 is a rotation || reflection
1647  if (!isUnitary(m)) {
1648  OPENVDB_THROW(ArithmeticError, "Matrix initializing unitary map was not unitary");
1649  }
1650 
1651  Mat4d matrix(Mat4d::identity());
1652  matrix.setMat3(m);
1653  mAffineMap = AffineMap(matrix);
1654  }
1655 
1656  UnitaryMap(const Mat4d& m)
1657  {
1658  if (!isInvertible(m)) {
1660  "4x4 Matrix initializing unitary map was not unitary: not invertible");
1661  }
1662 
1663  if (!isAffine(m)) {
1665  "4x4 Matrix initializing unitary map was not unitary: not affine");
1666  }
1667 
1668  if (hasTranslation(m)) {
1670  "4x4 Matrix initializing unitary map was not unitary: had translation");
1671  }
1672 
1673  if (!isUnitary(m.getMat3())) {
1675  "4x4 Matrix initializing unitary map was not unitary");
1676  }
1677 
1678  mAffineMap = AffineMap(m);
1679  }
1680 
1681  UnitaryMap(const UnitaryMap& other):
1682  MapBase(other),
1683  mAffineMap(other.mAffineMap)
1684  {
1685  }
1686 
1687  UnitaryMap(const UnitaryMap& first, const UnitaryMap& second):
1688  mAffineMap(*(first.getAffineMap()), *(second.getAffineMap()))
1689  {
1690  }
1691 
1694  static MapBase::Ptr create() { return MapBase::Ptr(new UnitaryMap()); }
1696  MapBase::Ptr copy() const { return MapBase::Ptr(new UnitaryMap(*this)); }
1697 
1699  {
1700  return MapBase::Ptr(new UnitaryMap(mAffineMap.getMat4().inverse()));
1701  }
1702 
1703  static bool isRegistered() { return MapRegistry::isRegistered(UnitaryMap::mapType()); }
1704 
1705  static void registerMap()
1706  {
1707  MapRegistry::registerMap(
1708  UnitaryMap::mapType(),
1709  UnitaryMap::create);
1710  }
1711 
1713  Name type() const { return mapType(); }
1715  static Name mapType() { return Name("UnitaryMap"); }
1716 
1718  bool isLinear() const { return true; }
1719 
1721  bool hasUniformScale() const { return true; }
1722 
1723  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
1724 
1725  bool operator==(const UnitaryMap& other) const
1726  {
1727  // compare underlying linear map.
1728  if (mAffineMap!=other.mAffineMap) return false;
1729  return true;
1730  }
1731 
1732  bool operator!=(const UnitaryMap& other) const { return !(*this == other); }
1734  Vec3d applyMap(const Vec3d& in) const { return mAffineMap.applyMap(in); }
1736  Vec3d applyInverseMap(const Vec3d& in) const { return mAffineMap.applyInverseMap(in); }
1737 
1738  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const { return applyJacobian(in); }
1740  Vec3d applyJacobian(const Vec3d& in) const { return mAffineMap.applyJacobian(in); }
1741 
1743  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const { return applyInverseJacobian(in); }
1745  Vec3d applyInverseJacobian(const Vec3d& in) const { return mAffineMap.applyInverseJacobian(in); }
1746 
1747 
1750  Vec3d applyJT(const Vec3d& in, const Vec3d&) const { return applyJT(in); }
1752  Vec3d applyJT(const Vec3d& in) const {
1753  // The transpose of the unitary map is its inverse
1754  return applyInverseMap(in);
1755  }
1756 
1757 
1760  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const { return applyIJT(in);}
1762  Vec3d applyIJT(const Vec3d& in) const { return mAffineMap.applyIJT(in); }
1764  Mat3d applyIJC(const Mat3d& in) const { return mAffineMap.applyIJC(in); }
1765  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d& ) const { return applyIJC(in); }
1767  double determinant(const Vec3d& ) const { return determinant(); }
1769  double determinant() const { return mAffineMap.determinant(); }
1770 
1771 
1776  Vec3d voxelSize() const { return mAffineMap.voxelSize();}
1777  Vec3d voxelSize(const Vec3d&) const { return voxelSize();}
1778 
1780  void read(std::istream& is)
1781  {
1782  mAffineMap.read(is);
1783  }
1784 
1786  void write(std::ostream& os) const
1787  {
1788  mAffineMap.write(os);
1789  }
1791  std::string str() const
1792  {
1793  std::ostringstream buffer;
1794  buffer << mAffineMap.str();
1795  return buffer.str();
1796  }
1798  AffineMap::Ptr getAffineMap() const { return AffineMap::Ptr(new AffineMap(mAffineMap)); }
1799 
1801  MapBase::Ptr preRotate(double radians, Axis axis) const
1804  {
1805  UnitaryMap first(axis, radians);
1806  UnitaryMap::Ptr unitaryMap(new UnitaryMap(first, *this));
1807  return boost::static_pointer_cast<MapBase, UnitaryMap>(unitaryMap);
1808  }
1810  {
1811  AffineMap::Ptr affineMap = getAffineMap();
1812  affineMap->accumPreTranslation(t);
1813  return simplify(affineMap);
1814  }
1815  MapBase::Ptr preScale(const Vec3d& v) const
1816  {
1817  AffineMap::Ptr affineMap = getAffineMap();
1818  affineMap->accumPreScale(v);
1819  return simplify(affineMap);
1820  }
1821  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
1822  {
1823  AffineMap::Ptr affineMap = getAffineMap();
1824  affineMap->accumPreShear(axis0, axis1, shear);
1825  return simplify(affineMap);
1826  }
1828 
1829 
1831  MapBase::Ptr postRotate(double radians, Axis axis) const
1834  {
1835  UnitaryMap second(axis, radians);
1836  UnitaryMap::Ptr unitaryMap(new UnitaryMap(*this, second));
1837  return boost::static_pointer_cast<MapBase, UnitaryMap>(unitaryMap);
1838  }
1840  {
1841  AffineMap::Ptr affineMap = getAffineMap();
1842  affineMap->accumPostTranslation(t);
1843  return simplify(affineMap);
1844  }
1845  MapBase::Ptr postScale(const Vec3d& v) const
1846  {
1847  AffineMap::Ptr affineMap = getAffineMap();
1848  affineMap->accumPostScale(v);
1849  return simplify(affineMap);
1850  }
1851  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
1852  {
1853  AffineMap::Ptr affineMap = getAffineMap();
1854  affineMap->accumPostShear(axis0, axis1, shear);
1855  return simplify(affineMap);
1856  }
1858 
1859 private:
1860  AffineMap mAffineMap;
1861 }; // class UnitaryMap
1862 
1863 
1865 
1866 
1874 {
1875 public:
1876  typedef boost::shared_ptr<NonlinearFrustumMap> Ptr;
1877  typedef boost::shared_ptr<const NonlinearFrustumMap> ConstPtr;
1878 
1880  MapBase(),
1881  mBBox(Vec3d(0), Vec3d(1)),
1882  mTaper(1),
1883  mDepth(1)
1884  {
1885  init();
1886  }
1887 
1891  NonlinearFrustumMap(const BBoxd& bb, double taper, double depth):
1892  MapBase(),mBBox(bb), mTaper(taper), mDepth(depth)
1893  {
1894  init();
1895  }
1896 
1902  NonlinearFrustumMap(const BBoxd& bb, double taper, double depth,
1903  const MapBase::Ptr& secondMap):
1904  mBBox(bb), mTaper(taper), mDepth(depth)
1905  {
1906  if (!secondMap->isLinear() ) {
1908  "The second map in the Frustum transfrom must be linear");
1909  }
1910  mSecondMap = *( secondMap->getAffineMap() );
1911  init();
1912  }
1913 
1915  MapBase(),
1916  mBBox(other.mBBox),
1917  mTaper(other.mTaper),
1918  mDepth(other.mDepth),
1919  mSecondMap(other.mSecondMap),
1920  mHasSimpleAffine(other.mHasSimpleAffine)
1921  {
1922  init();
1923  }
1924 
1940  NonlinearFrustumMap(const Vec3d& position,
1941  const Vec3d& direction,
1942  const Vec3d& up,
1943  double aspect /* width / height */,
1944  double z_near, double depth,
1945  Coord::ValueType x_count, Coord::ValueType z_count) {
1946 
1950  if (!(depth > 0)) {
1952  "The frustum depth must be non-zero and positive");
1953  }
1954  if (!(up.length() > 0)) {
1956  "The frustum height must be non-zero and positive");
1957  }
1958  if (!(aspect > 0)) {
1960  "The frustum aspect ratio must be non-zero and positive");
1961  }
1962  if (!(isApproxEqual(up.dot(direction), 0.))) {
1964  "The frustum up orientation must be perpendicular to into-frustum direction");
1965  }
1966 
1967  double near_plane_height = 2 * up.length();
1968  double near_plane_width = aspect * near_plane_height;
1969 
1970  Coord::ValueType y_count = static_cast<int>(Round(x_count / aspect));
1971 
1972  mBBox = BBoxd(Vec3d(0,0,0), Vec3d(x_count, y_count, z_count));
1973  mDepth = depth / near_plane_width; // depth non-dimensionalized on width
1974  double gamma = near_plane_width / z_near;
1975  mTaper = 1./(mDepth*gamma + 1.);
1976 
1977  Vec3d direction_unit = direction;
1978  direction_unit.normalize();
1979 
1980  Mat4d r1(Mat4d::identity());
1981  r1.setToRotation(/*from*/Vec3d(0,0,1), /*to */direction_unit);
1982  Mat4d r2(Mat4d::identity());
1983  Vec3d temp = r1.inverse().transform(up);
1984  r2.setToRotation(/*from*/Vec3d(0,1,0), /*to*/temp );
1985  Mat4d scale = math::scale<Mat4d>(
1986  Vec3d(near_plane_width, near_plane_width, near_plane_width));
1987 
1988  // move the near plane to origin, rotate to align with axis, and scale down
1989  // T_inv * R1_inv * R2_inv * scale_inv
1990  Mat4d mat = scale * r2 * r1;
1991  mat.setTranslation(position + z_near*direction_unit);
1992 
1993  mSecondMap = AffineMap(mat);
1994 
1995  init();
1996  }
1997 
2002  MapBase::Ptr copy() const { return MapBase::Ptr(new NonlinearFrustumMap(*this)); }
2003 
2008  {
2010  "inverseMap() is not implemented for NonlinearFrustumMap");
2011  }
2012  static bool isRegistered() { return MapRegistry::isRegistered(NonlinearFrustumMap::mapType()); }
2013 
2014  static void registerMap()
2015  {
2016  MapRegistry::registerMap(
2017  NonlinearFrustumMap::mapType(),
2018  NonlinearFrustumMap::create);
2019  }
2021  Name type() const { return mapType(); }
2023  static Name mapType() { return Name("NonlinearFrustumMap"); }
2024 
2026  bool isLinear() const { return false; }
2027 
2029  bool hasUniformScale() const { return false; }
2030 
2032  bool isIdentity() const
2033  {
2034  // The frustum can only be consistent with a linear map if the taper value is 1
2035  if (!isApproxEqual(mTaper, double(1)) ) return false;
2036 
2037  // There are various ways an identity can decomposed between the two parts of the
2038  // map. Best to just check that the principle vectors are stationary.
2039  const Vec3d e1(1,0,0);
2040  if (!applyMap(e1).eq(e1)) return false;
2041 
2042  const Vec3d e2(0,1,0);
2043  if (!applyMap(e2).eq(e2)) return false;
2044 
2045  const Vec3d e3(0,0,1);
2046  if (!applyMap(e3).eq(e3)) return false;
2047 
2048  return true;
2049  }
2050 
2051  virtual bool isEqual(const MapBase& other) const { return isEqualBase(*this, other); }
2052 
2053  bool operator==(const NonlinearFrustumMap& other) const
2054  {
2055  if (mBBox!=other.mBBox) return false;
2056  if (!isApproxEqual(mTaper, other.mTaper)) return false;
2057  if (!isApproxEqual(mDepth, other.mDepth)) return false;
2058 
2059  // Two linear transforms are equivalent iff they have the same translation
2060  // and have the same affects on orthongal spanning basis check translation
2061  Vec3d e(0,0,0);
2062  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2064  e(0) = 1;
2065  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2066  e(0) = 0;
2067  e(1) = 1;
2068  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2069  e(1) = 0;
2070  e(2) = 1;
2071  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2072  return true;
2073  }
2074 
2075  bool operator!=(const NonlinearFrustumMap& other) const { return !(*this == other); }
2076 
2078  Vec3d applyMap(const Vec3d& in) const
2079  {
2080  return mSecondMap.applyMap(applyFrustumMap(in));
2081  }
2082 
2084  Vec3d applyInverseMap(const Vec3d& in) const
2085  {
2086  return applyFrustumInverseMap(mSecondMap.applyInverseMap(in));
2087  }
2089  Vec3d applyJacobian(const Vec3d& in) const { return mSecondMap.applyJacobian(in); }
2091  Vec3d applyJacobian(const Vec3d& in, const Vec3d& isloc) const
2092  {
2093  // Move the center of the x-face of the bbox
2094  // to the origin in index space.
2095  Vec3d centered(isloc);
2096  centered = centered - mBBox.min();
2097  centered.x() -= mXo;
2098  centered.y() -= mYo;
2099 
2100  // scale the z-direction on depth / K count
2101  const double zprime = centered.z()*mDepthOnLz;
2102 
2103  const double scale = (mGamma * zprime + 1.) / mLx;
2104  const double scale2 = mGamma * mDepthOnLz / mLx;
2105 
2106  const Vec3d tmp(scale * in.x() + scale2 * centered.x()* in.z(),
2107  scale * in.y() + scale2 * centered.y()* in.z(),
2108  mDepthOnLz * in.z());
2109 
2110  return mSecondMap.applyJacobian(tmp);
2111  }
2112 
2113 
2115  Vec3d applyInverseJacobian(const Vec3d& in) const { return mSecondMap.applyInverseJacobian(in); }
2117  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d& isloc) const {
2118 
2119  // Move the center of the x-face of the bbox
2120  // to the origin in index space.
2121  Vec3d centered(isloc);
2122  centered = centered - mBBox.min();
2123  centered.x() -= mXo;
2124  centered.y() -= mYo;
2125 
2126  // scale the z-direction on depth / K count
2127  const double zprime = centered.z()*mDepthOnLz;
2128 
2129  const double scale = (mGamma * zprime + 1.) / mLx;
2130  const double scale2 = mGamma * mDepthOnLz / mLx;
2131 
2132 
2133  Vec3d out = mSecondMap.applyInverseJacobian(in);
2134 
2135  out.x() = (out.x() - scale2 * centered.x() * out.z() / mDepthOnLz) / scale;
2136  out.y() = (out.y() - scale2 * centered.y() * out.z() / mDepthOnLz) / scale;
2137  out.z() = out.z() / mDepthOnLz;
2138 
2139  return out;
2140  }
2141 
2142 
2143 
2147  Vec3d applyJT(const Vec3d& in, const Vec3d& isloc) const {
2148  const Vec3d tmp = mSecondMap.applyJT(in);
2149  // Move the center of the x-face of the bbox
2150  // to the origin in index space.
2151  Vec3d centered(isloc);
2152  centered = centered - mBBox.min();
2153  centered.x() -= mXo;
2154  centered.y() -= mYo;
2155 
2156  // scale the z-direction on depth / K count
2157  const double zprime = centered.z()*mDepthOnLz;
2158 
2159  const double scale = (mGamma * zprime + 1.) / mLx;
2160  const double scale2 = mGamma * mDepthOnLz / mLx;
2161 
2162  return Vec3d(scale * tmp.x(),
2163  scale * tmp.y(),
2164  scale2 * centered.x()* tmp.x() +
2165  scale2 * centered.y()* tmp.y() +
2166  mDepthOnLz * tmp.z());
2167  }
2169  Vec3d applyJT(const Vec3d& in) const {
2170  return mSecondMap.applyJT(in);
2171  }
2172 
2174  Vec3d applyIJT(const Vec3d& in) const { return mSecondMap.applyIJT(in); }
2175 
2176  // the Jacobian of the nonlinear part of the transform is a sparse matrix
2177  // Jacobian^(-T) =
2178  //
2179  // (Lx)( 1/s 0 0 )
2180  // ( 0 1/s 0 )
2181  // ( -(x-xo)g/(sLx) -(y-yo)g/(sLx) Lz/(Depth Lx) )
2184  Vec3d applyIJT(const Vec3d& d1_is, const Vec3d& ijk) const
2185  {
2186  const Vec3d loc = applyFrustumMap(ijk);
2187  const double s = mGamma * loc.z() + 1.;
2188 
2189  // verify that we aren't at the singularity
2190  if (isApproxEqual(s, 0.)) {
2191  OPENVDB_THROW(ArithmeticError, "Tried to evaluate the frustum transform"
2192  " at the singular focal point (e.g. camera)");
2193  }
2194 
2195  const double sinv = 1.0/s; // 1/(z*gamma + 1)
2196  const double pt0 = mLx * sinv; // Lx / (z*gamma +1)
2197  const double pt1 = mGamma * pt0; // gamma * Lx / ( z*gamma +1)
2198  const double pt2 = pt1 * sinv; // gamma * Lx / ( z*gamma +1)**2
2199 
2200  const Mat3d& jacinv = mSecondMap.getConstJacobianInv();
2201 
2202  // compute \frac{\partial E_i}{\partial x_j}
2203  Mat3d gradE(Mat3d::zero());
2204  for (int j = 0; j < 3; ++j ) {
2205  gradE(0,j) = pt0 * jacinv(0,j) - pt2 * loc.x()*jacinv(2,j);
2206  gradE(1,j) = pt0 * jacinv(1,j) - pt2 * loc.y()*jacinv(2,j);
2207  gradE(2,j) = (1./mDepthOnLz) * jacinv(2,j);
2208  }
2209 
2210  Vec3d result;
2211  for (int i = 0; i < 3; ++i) {
2212  result(i) = d1_is(0) * gradE(0,i) + d1_is(1) * gradE(1,i) + d1_is(2) * gradE(2,i);
2213  }
2214 
2215  return result;
2216 
2217  }
2218 
2220  Mat3d applyIJC(const Mat3d& in) const { return mSecondMap.applyIJC(in); }
2225  Mat3d applyIJC(const Mat3d& d2_is, const Vec3d& d1_is, const Vec3d& ijk) const
2226  {
2227  const Vec3d loc = applyFrustumMap(ijk);
2228 
2229  const double s = mGamma * loc.z() + 1.;
2230 
2231  // verify that we aren't at the singularity
2232  if (isApproxEqual(s, 0.)) {
2233  OPENVDB_THROW(ArithmeticError, "Tried to evaluate the frustum transform"
2234  " at the singular focal point (e.g. camera)");
2235  }
2236 
2237  // precompute
2238  const double sinv = 1.0/s; // 1/(z*gamma + 1)
2239  const double pt0 = mLx * sinv; // Lx / (z*gamma +1)
2240  const double pt1 = mGamma * pt0; // gamma * Lx / ( z*gamma +1)
2241  const double pt2 = pt1 * sinv; // gamma * Lx / ( z*gamma +1)**2
2242  const double pt3 = pt2 * sinv; // gamma * Lx / ( z*gamma +1)**3
2243 
2244  const Mat3d& jacinv = mSecondMap.getConstJacobianInv();
2245 
2246  // compute \frac{\partial^2 E_i}{\partial x_j \partial x_k}
2247 
2248  Mat3d matE0(Mat3d::zero());
2249  Mat3d matE1(Mat3d::zero()); // matE2 = 0
2250  for(int j = 0; j < 3; j++) {
2251  for (int k = 0; k < 3; k++) {
2252 
2253  const double pt4 = 2. * jacinv(2,j) * jacinv(2,k) * pt3;
2254 
2255  matE0(j,k) = -(jacinv(0,j) * jacinv(2,k) + jacinv(2,j) * jacinv(0,k)) * pt2 +
2256  pt4 * loc.x();
2257 
2258  matE1(j,k) = -(jacinv(1,j) * jacinv(2,k) + jacinv(2,j) * jacinv(1,k)) * pt2 +
2259  pt4 * loc.y();
2260  }
2261  }
2262 
2263  // compute \frac{\partial E_i}{\partial x_j}
2264  Mat3d gradE(Mat3d::zero());
2265  for (int j = 0; j < 3; ++j ) {
2266  gradE(0,j) = pt0 * jacinv(0,j) - pt2 * loc.x()*jacinv(2,j);
2267  gradE(1,j) = pt0 * jacinv(1,j) - pt2 * loc.y()*jacinv(2,j);
2268  gradE(2,j) = (1./mDepthOnLz) * jacinv(2,j);
2269  }
2270 
2271  Mat3d result(Mat3d::zero());
2272  // compute \fac{\partial E_j}{\partial x_m} \fac{\partial E_i}{\partial x_n}
2273  // \frac{\partial^2 input}{\partial E_i \partial E_j}
2274  for (int m = 0; m < 3; ++m ) {
2275  for ( int n = 0; n < 3; ++n) {
2276  for (int i = 0; i < 3; ++i ) {
2277  for (int j = 0; j < 3; ++j) {
2278  result(m, n) += gradE(j, m) * gradE(i, n) * d2_is(i, j);
2279  }
2280  }
2281  }
2282  }
2283 
2284  for (int m = 0; m < 3; ++m ) {
2285  for ( int n = 0; n < 3; ++n) {
2286  result(m, n) +=
2287  matE0(m, n) * d1_is(0) + matE1(m, n) * d1_is(1);// + matE2(m, n) * d1_is(2);
2288  }
2289  }
2290 
2291  return result;
2292  }
2293 
2295  double determinant() const {return mSecondMap.determinant();} // no implementation
2296 
2299  double determinant(const Vec3d& loc) const
2300  {
2301  double s = mGamma * loc.z() + 1.0;
2302  double frustum_determinant = s * s * mDepthOnLzLxLx;
2303  return mSecondMap.determinant() * frustum_determinant;
2304  }
2305 
2308  {
2309  const Vec3d loc( 0.5*(mBBox.min().x() + mBBox.max().x()),
2310  0.5*(mBBox.min().y() + mBBox.max().y()),
2311  mBBox.min().z());
2312 
2313  return voxelSize(loc);
2314 
2315  }
2316 
2321  Vec3d voxelSize(const Vec3d& loc) const
2322  {
2323  Vec3d out, pos = applyMap(loc);
2324  out(0) = (applyMap(loc + Vec3d(1,0,0)) - pos).length();
2325  out(1) = (applyMap(loc + Vec3d(0,1,0)) - pos).length();
2326  out(2) = (applyMap(loc + Vec3d(0,0,1)) - pos).length();
2327  return out;
2328  }
2329 
2330  AffineMap::Ptr getAffineMap() const { return mSecondMap.getAffineMap(); }
2331 
2333  void setTaper(double t) { mTaper = t; init();}
2335  double getTaper() const { return mTaper; }
2337  void setDepth(double d) { mDepth = d; init();}
2339  double getDepth() const { return mDepth; }
2340  // gamma a non-dimensional number: nearplane x-width / camera to near plane distance
2341  double getGamma() const { return mGamma; }
2342 
2344  const BBoxd& getBBox() const { return mBBox; }
2345 
2347  const AffineMap& secondMap() const { return mSecondMap; }
2350  bool isValid() const { return !mBBox.empty();}
2351 
2353  bool hasSimpleAffine() const { return mHasSimpleAffine; }
2354 
2356  void read(std::istream& is)
2357  {
2358  // for backward compatibility with earlier version
2360  CoordBBox bb;
2361  bb.read(is);
2362  mBBox = BBoxd(bb.min().asVec3d(), bb.max().asVec3d());
2363  } else {
2364  mBBox.read(is);
2365  }
2366 
2367  is.read(reinterpret_cast<char*>(&mTaper), sizeof(double));
2368  is.read(reinterpret_cast<char*>(&mDepth), sizeof(double));
2369 
2370  // Read the second maps type.
2371  Name type = readString(is);
2372 
2373  // Check if the map has been registered.
2374  if(!MapRegistry::isRegistered(type)) {
2375  OPENVDB_THROW(KeyError, "Map " << type << " is not registered");
2376  }
2377 
2378  // Create the second map of the type and then read it in.
2379  MapBase::Ptr proxy = math::MapRegistry::createMap(type);
2380  proxy->read(is);
2381  mSecondMap = *(proxy->getAffineMap());
2382  init();
2383  }
2384 
2386  void write(std::ostream& os) const
2387  {
2388  mBBox.write(os);
2389  os.write(reinterpret_cast<const char*>(&mTaper), sizeof(double));
2390  os.write(reinterpret_cast<const char*>(&mDepth), sizeof(double));
2391 
2392  writeString(os, mSecondMap.type());
2393  mSecondMap.write(os);
2394  }
2395 
2397  std::string str() const
2398  {
2399  std::ostringstream buffer;
2400  buffer << " - taper: " << mTaper << std::endl;
2401  buffer << " - depth: " << mDepth << std::endl;
2402  buffer << " SecondMap: "<< mSecondMap.type() << std::endl;
2403  buffer << mSecondMap.str() << std::endl;
2404  return buffer.str();
2405  }
2406 
2408  MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const
2411  {
2412  return MapBase::Ptr(
2413  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preRotate(radians, axis)));
2414  }
2416  {
2417  return MapBase::Ptr(
2418  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preTranslate(t)));
2419  }
2420  MapBase::Ptr preScale(const Vec3d& s) const
2421  {
2422  return MapBase::Ptr(
2423  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preScale(s)));
2424  }
2425  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const
2426  {
2427  return MapBase::Ptr(new NonlinearFrustumMap(
2428  mBBox, mTaper, mDepth, mSecondMap.preShear(shear, axis0, axis1)));
2429  }
2431 
2433  MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const
2436  {
2437  return MapBase::Ptr(
2438  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postRotate(radians, axis)));
2439  }
2441  {
2442  return MapBase::Ptr(
2443  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postTranslate(t)));
2444  }
2445  MapBase::Ptr postScale(const Vec3d& s) const
2446  {
2447  return MapBase::Ptr(
2448  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postScale(s)));
2449  }
2450  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const
2451  {
2452  return MapBase::Ptr(new NonlinearFrustumMap(
2453  mBBox, mTaper, mDepth, mSecondMap.postShear(shear, axis0, axis1)));
2454  }
2456 
2457 private:
2458  void init()
2459  {
2460  // set up as a frustum
2461  mLx = mBBox.extents().x();
2462  mLy = mBBox.extents().y();
2463  mLz = mBBox.extents().z();
2464 
2465  if (isApproxEqual(mLx,0.) || isApproxEqual(mLy,0.) || isApproxEqual(mLz,0.) ) {
2466  OPENVDB_THROW(ArithmeticError, "The index space bounding box"
2467  " must have at least two index points in each direction.");
2468  }
2469 
2470  mXo = 0.5* mLx;
2471  mYo = 0.5* mLy;
2472 
2473  // mDepth is non-dimensionalized on near
2474  mGamma = (1./mTaper - 1) / mDepth;
2475 
2476  mDepthOnLz = mDepth/mLz;
2477  mDepthOnLzLxLx = mDepthOnLz/(mLx * mLx);
2478 
2480  mHasSimpleAffine = true;
2481  Vec3d tmp = mSecondMap.voxelSize();
2482 
2484  if (!isApproxEqual(tmp(0), tmp(1))) { mHasSimpleAffine = false; return; }
2485  if (!isApproxEqual(tmp(0), tmp(2))) { mHasSimpleAffine = false; return; }
2486 
2487  Vec3d trans = mSecondMap.applyMap(Vec3d(0,0,0));
2489  Vec3d tmp1 = mSecondMap.applyMap(Vec3d(1,0,0)) - trans;
2490  Vec3d tmp2 = mSecondMap.applyMap(Vec3d(0,1,0)) - trans;
2491  Vec3d tmp3 = mSecondMap.applyMap(Vec3d(0,0,1)) - trans;
2492 
2494  if (!isApproxEqual(tmp1.dot(tmp2), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2495  if (!isApproxEqual(tmp2.dot(tmp3), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2496  if (!isApproxEqual(tmp3.dot(tmp1), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2497  }
2498 
2499  Vec3d applyFrustumMap(const Vec3d& in) const
2500  {
2501 
2502  // Move the center of the x-face of the bbox
2503  // to the origin in index space.
2504  Vec3d out(in);
2505  out = out - mBBox.min();
2506  out.x() -= mXo;
2507  out.y() -= mYo;
2508 
2509  // scale the z-direction on depth / K count
2510  out.z() *= mDepthOnLz;
2511 
2512  double scale = (mGamma * out.z() + 1.)/ mLx;
2513 
2514  // scale the x-y on the length I count and apply tapper
2515  out.x() *= scale ;
2516  out.y() *= scale ;
2517 
2518  return out;
2519  }
2520 
2521  Vec3d applyFrustumInverseMap(const Vec3d& in) const
2522  {
2523  // invert taper and resize: scale = 1/( (z+1)/2 (mt-1) + 1)
2524  Vec3d out(in);
2525  double invScale = mLx / (mGamma * out.z() + 1.);
2526  out.x() *= invScale;
2527  out.y() *= invScale;
2528 
2529  out.x() += mXo;
2530  out.y() += mYo;
2531 
2532  out.z() /= mDepthOnLz;
2533 
2534  // move back
2535  out = out + mBBox.min();
2536  return out;
2537  }
2538 
2539  // bounding box in index space used in Frustum transforms.
2540  BBoxd mBBox;
2541 
2542  // taper value used in constructing Frustums.
2543  double mTaper;
2544  double mDepth;
2545 
2546  // defines the second map
2547  AffineMap mSecondMap;
2548 
2549  // these are derived from the above.
2550  double mLx, mLy, mLz;
2551  double mXo, mYo, mGamma, mDepthOnLz, mDepthOnLzLxLx;
2552 
2553  // true: if the mSecondMap is linear and has no shear, and has no non-uniform scale
2554  bool mHasSimpleAffine;
2555 }; // class NonlinearFrustumMap
2556 
2557 
2559 
2560 
2564 template<typename FirstMapType, typename SecondMapType>
2565 class CompoundMap
2566 {
2567 public:
2569 
2570  typedef boost::shared_ptr<MyType> Ptr;
2571  typedef boost::shared_ptr<const MyType> ConstPtr;
2572 
2573 
2574  CompoundMap() { updateAffineMatrix(); }
2575 
2576  CompoundMap(const FirstMapType& f, const SecondMapType& s): mFirstMap(f), mSecondMap(s)
2577  {
2578  updateAffineMatrix();
2579  }
2580 
2581  CompoundMap(const MyType& other):
2582  mFirstMap(other.mFirstMap),
2583  mSecondMap(other.mSecondMap),
2584  mAffineMap(other.mAffineMap)
2585  {}
2586 
2587  Name type() const { return mapType(); }
2588  static Name mapType()
2589  {
2590  return (FirstMapType::mapType() + Name(":") + SecondMapType::mapType());
2591  }
2592 
2593  bool operator==(const MyType& other) const
2594  {
2595  if (mFirstMap != other.mFirstMap) return false;
2596  if (mSecondMap != other.mSecondMap) return false;
2597  if (mAffineMap != other.mAffineMap) return false;
2598  return true;
2599  }
2600 
2601  bool operator!=(const MyType& other) const { return !(*this == other); }
2602 
2603  MyType& operator=(const MyType& other)
2604  {
2605  mFirstMap = other.mFirstMap;
2606  mSecondMap = other.mSecondMap;
2607  mAffineMap = other.mAffineMap;
2608  return *this;
2609  }
2610 
2611  bool isIdentity() const
2612  {
2614  return mAffineMap.isIdentity();
2615  } else {
2616  return mFirstMap.isIdentity()&&mSecondMap.isIdentity();
2617  }
2618  }
2619 
2620  bool isDiagonal() const {
2622  return mAffineMap.isDiagonal();
2623  } else {
2624  return mFirstMap.isDiagonal()&&mSecondMap.isDiagonal();
2625  }
2626  }
2627 
2629  {
2631  AffineMap::Ptr affine(new AffineMap(mAffineMap));
2632  return affine;
2633  } else {
2635  "Constant affine matrix representation not possible for this nonlinear map");
2636  }
2637  }
2638 
2639  // direct decompotion
2640  const FirstMapType& firstMap() const { return mFirstMap; }
2641  const SecondMapType& secondMap() const {return mSecondMap; }
2642 
2643  void setFirstMap(const FirstMapType& first) { mFirstMap = first; updateAffineMatrix(); }
2644  void setSecondMap(const SecondMapType& second) { mSecondMap = second; updateAffineMatrix(); }
2645 
2646  void read(std::istream& is)
2647  {
2648  mAffineMap.read(is);
2649  mFirstMap.read(is);
2650  mSecondMap.read(is);
2651  }
2652  void write(std::ostream& os) const
2653  {
2654  mAffineMap.write(os);
2655  mFirstMap.write(os);
2656  mSecondMap.write(os);
2657  }
2658 
2659 private:
2660  void updateAffineMatrix()
2661  {
2663  // both maps need to be linear, these methods are only defined for linear maps
2664  AffineMap::Ptr first = mFirstMap.getAffineMap();
2665  AffineMap::Ptr second= mSecondMap.getAffineMap();
2666  mAffineMap = AffineMap(*first, *second);
2667  }
2668  }
2669 
2670  FirstMapType mFirstMap;
2671  SecondMapType mSecondMap;
2672  // used for acceleration
2673  AffineMap mAffineMap;
2674 }; // class CompoundMap
2675 
2676 } // namespace math
2677 } // namespace OPENVDB_VERSION_NAME
2678 } // namespace openvdb
2679 
2680 #endif // OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
2681 
2682 // Copyright (c) 2012-2013 DreamWorks Animation LLC
2683 // All rights reserved. This software is distributed under the
2684 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Vec3d applyJacobian(const Vec3d &in, const Vec3d &isloc) const
Return the Jacobian defined at isloc applied to in.
Definition: Maps.h:2091
bool operator!=(const NonlinearFrustumMap &other) const
Definition: Maps.h:2075
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1043
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...
ScaleTranslateMap(const ScaleMap &scale, const TranslationMap &translate)
Definition: Maps.h:1205
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:1059
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:1417
Mat3d applyIJC(const Mat3d &d2_is, const Vec3d &d1_is, const Vec3d &ijk) const
Definition: Maps.h:2225
const Coord & max() const
Definition: Coord.h:258
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:605
void accumPostTranslation(const Vec3d &v)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:536
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:229
boost::shared_ptr< const MapBase > ConstPtr
Definition: Maps.h:162
Vec3< T > col(int j) const
Get jth column, e.g. Vec3d v = m.col(0);.
Definition: Mat3.h:184
virtual ~MapBase()
Definition: Maps.h:165
Type Round(Type x)
Return x rounded down to the nearest integer.
Definition: Math.h:698
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:187
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:2397
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:441
const Vec3d & getTranslation() const
Return the translation vector.
Definition: Maps.h:1078
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:1122
Mat3< T > getMat3() const
Definition: Mat4.h:302
OPENVDB_API Mat4d approxInverse(const Mat4d &mat)
Returns the left pseudoInverse of the input matrix when the 3x3 part is symmetric otherwise it zeros ...
const Vec3d & getInvScale() const
Return 1/(scale)
Definition: Maps.h:817
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the second map applied to in.
Definition: Maps.h:2169
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:593
CompoundMap< CompoundMap< UnitaryMap, ScaleMap >, UnitaryMap > SpectralDecomposedMap
Definition: Maps.h:69
boost::shared_ptr< MyType > Ptr
Definition: Maps.h:2570
void setTaper(double t)
set the taper value, the ratio of nearplane width / far plane width
Definition: Maps.h:2333
const Vec3d & getInvTwiceScale() const
Return 1/(2 scale). Used to optimize some finite difference calculations.
Definition: Maps.h:1343
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1496
bool isValid() const
Definition: Maps.h:2350
TranslationMap(const Vec3d &t)
Definition: Maps.h:1006
UnitaryMap()
default constructor makes an Idenity.
Definition: Maps.h:1626
const Vec3d & getInvTwiceScale() const
Return 1/(2 scale). Used to optimize some finite difference calculations.
Definition: Maps.h:815
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:439
OPENVDB_API boost::shared_ptr< SymmetricMap > createSymmetricMap(const Mat3d &m)
Utility methods.
~NonlinearFrustumMap()
Definition: Maps.h:1998
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:788
static MapBase::Ptr create()
Return a MapBase::Ptr to a new NonlinearFrustumMap.
Definition: Maps.h:2000
Vec3d voxelSize() const
Returns the lengths of the images of the segments , , .
Definition: Maps.h:1776
ScaleTranslateMap(const Vec3d &scale, const Vec3d &translate)
Definition: Maps.h:1190
math::BBox< Vec3d > BBoxd
Definition: Types.h:85
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
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:774
double determinant(const Vec3d &) const
Return the product of the scale values, ignores argument.
Definition: Maps.h:805
const FirstMapType & firstMap() const
Definition: Maps.h:2640
const Vec3d & getTranslation() const
Returns the translation.
Definition: Maps.h:1338
double getTaper() const
Return the taper value.
Definition: Maps.h:2335
A specialized Affine transform that uniformaly scales along the principal axis and then translates th...
Definition: Maps.h:1476
boost::shared_ptr< const ScaleTranslateMap > ConstPtr
Definition: Maps.h:1177
UniformScaleMap()
Definition: Maps.h:932
CompoundMap< SymmetricMap, UnitaryAndTranslationMap > FullyDecomposedMap
Definition: Maps.h:71
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:2440
static Name mapType()
Definition: Maps.h:957
double determinant(const Vec3d &) const
Return the determinant of the Jacobian, ignores argument.
Definition: Maps.h:476
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1302
ScaleTranslateMap()
Definition: Maps.h:1179
UniformScaleTranslateMap(const UniformScaleTranslateMap &other)
Definition: Maps.h:1488
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:1147
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:888
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the linear second map applied to in.
Definition: Maps.h:2174
T & z()
Definition: Vec3.h:96
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1016
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1010
static bool isRegistered()
Definition: Maps.h:948
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:1039
Definition: Exceptions.h:78
void accumPreTranslation(const Vec3d &v)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:511
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1764
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:1292
void accumPreScale(const Vec3d &v)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:506
UnitaryMap(const Mat4d &m)
Definition: Maps.h:1656
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:2321
Mat3 inverse(T tolerance=0) const
Definition: Mat3.h:466
This map is composed of three steps. Frist it will take a box of size (Lx X Ly X Lz) defined by an me...
Definition: Maps.h:1873
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:1296
static Name mapType()
Definition: Maps.h:396
ScaleTranslateMap(const ScaleTranslateMap &other)
Definition: Maps.h:1218
const Mat4d & getConstMat4() const
Definition: Maps.h:645
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
static Name mapType()
Definition: Maps.h:1251
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:344
void setDepth(double d)
set the frustum depth: distance between near and far plane = frustm depth * frustm x-width ...
Definition: Maps.h:2337
A specialized linear transform that performs a translation.
Definition: Maps.h:998
UnitaryMap(const UnitaryMap &other)
Definition: Maps.h:1681
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition: Mat4.h:795
Mat3< double > Mat3d
Definition: Mat3.h:666
const AffineMap & secondMap() const
Return MapBase::Ptr& to the second map.
Definition: Maps.h:2347
Definition: Maps.h:103
bool isScaleTranslate() const
Return true if the map is equivalent to a ScaleTranslateMap.
Definition: Maps.h:494
boost::shared_ptr< const ScaleMap > ConstPtr
Definition: Maps.h:688
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:1046
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:446
static bool isRegistered()
Definition: Maps.h:1018
static void registerMap()
Definition: Maps.h:388
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:1053
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1762
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:2117
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:1777
static void registerMap()
Definition: Maps.h:1508
double determinant() const
Return the product of the scale values.
Definition: Maps.h:1328
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:1537
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:940
void accumPostShear(Axis axis0, Axis axis1, double shear)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:541
static void registerMap()
Definition: Maps.h:1705
T length() const
Length of the vector.
Definition: Vec3.h:208
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:1528
bool operator!=(const TranslationMap &other) const
Definition: Maps.h:1100
bool hasUniformScale() const
Return false (by convention false)
Definition: Maps.h:2029
Name readString(std::istream &is)
Definition: Name.h:47
Mat3 transpose() const
returns transpose of this
Definition: Mat3.h:455
~ScaleTranslateMap()
Definition: Maps.h:1228
bool operator!=(const ScaleMap &other) const
Definition: Maps.h:864
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:1765
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:490
static const Mat4< double > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:147
static MapBase::Ptr create()
Return a MapBase::Ptr to a new ScaleMap.
Definition: Maps.h:721
bool isLinear() const
Return true (a UnitaryMap is always linear).
Definition: Maps.h:1718
~UnitaryMap()
Definition: Maps.h:1692
bool operator==(const AffineMap &other) const
Definition: Maps.h:416
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:1745
void read(std::istream &is)
read serialization
Definition: Maps.h:1080
bool operator!=(const ScaleTranslateMap &other) const
Definition: Maps.h:1387
AffineMap::Ptr inverse() const
Return AffineMap::Ptr to the inverse of this map.
Definition: Maps.h:581
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:1815
void accumPreShear(Axis axis0, Axis axis1, double shear)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:516
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:911
bool hasUniformScale() const
Return true if the scale values have the same magnitude (eg. -1, 1, -1 would be a rotation)...
Definition: Maps.h:1258
T * asPointer()
Definition: Vec3.h:103
void write(std::ostream &os) const
write serialization
Definition: Maps.h:1082
void read(std::istream &is)
Definition: Maps.h:2646
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:2115
AffineMap(const Mat4d &m)
Definition: Maps.h:349
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:599
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1233
UnitaryMap(Axis axis, double radians)
Definition: Maps.h:1637
void setToRotation(const Quat< T > &q)
Set this matrix to the rotation matrix specified by the quaternion.
Definition: Mat3.h:270
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1055
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:635
Name type() const
Return the name of this map's concrete type (e.g., "AffineMap").
Definition: Maps.h:1250
Definition: Math.h:768
static void registerMap()
Definition: Maps.h:729
void write(std::ostream &os) const
write serialization
Definition: Maps.h:2386
double determinant(const Vec3d &loc) const
Definition: Maps.h:2299
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition: Mat4.h:295
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:1791
Name type() const
Return the name of this map's concrete type (e.g., "AffineMap").
Definition: Maps.h:1027
boost::shared_ptr< const UnitaryMap > ConstPtr
Definition: Maps.h:1623
Threadsafe singleton object for accessing the map type-name dictionary. Associates a map type-name wi...
Definition: Maps.h:285
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:629
OPENVDB_API boost::shared_ptr< PolarDecomposedMap > createPolarDecomposedMap(const Mat3d &m)
Decomposes a general linear into translation following polar decomposition.
bool isScale() const
Return true if the map is equivalent to a ScaleMap.
Definition: Maps.h:492
bool operator!=(const MyType &other) const
Definition: Maps.h:2601
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:847
T & y()
Definition: Vec3.h:95
bool hasUniformScale() const
Return false ( test if this is unitary with translation )
Definition: Maps.h:402
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:2425
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:2078
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:1173
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1798
bool isLinear() const
Return true (an AffineMap is always linear).
Definition: Maps.h:399
boost::shared_ptr< NonlinearFrustumMap > Ptr
Definition: Maps.h:1876
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:384
Vec3d applyMap(const Vec3d &in) const
Return the image of under the map.
Definition: Maps.h:1268
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:1368
AffineMap(const Mat3d &m)
Definition: Maps.h:341
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1298
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:1323
Vec3d voxelSize(const Vec3d &) const
Definition: Maps.h:1333
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1235
boost::shared_ptr< const UniformScaleTranslateMap > ConstPtr
Definition: Maps.h:1480
bool operator!=(const AffineMap &other) const
Definition: Maps.h:424
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:1738
boost::shared_ptr< AffineMap > Ptr
Definition: Maps.h:326
bool isUnitary(const MatType &m)
Determine if a matrix is unitary (i.e., rotation or reflection).
Definition: Mat.h:862
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:666
boost::shared_ptr< FullyDecomposedMap > createDecomposedMap()
on-demand decomposition of the affine map
Definition: Maps.h:572
CompoundMap(const FirstMapType &f, const SecondMapType &s)
Definition: Maps.h:2576
double determinant() const
Return the determinant of the Jacobian.
Definition: Maps.h:478
boost::shared_ptr< TranslationMap > Ptr
Definition: Maps.h:1001
AffineMap()
Definition: Maps.h:329
bool isLinear() const
Return false (a NonlinearFrustumMap is never linear).
Definition: Maps.h:2026
boost::shared_ptr< UniformScaleMap > Ptr
Definition: Maps.h:929
CompoundMap< FirstMapType, SecondMapType > MyType
Definition: Maps.h:2568
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the linear second map applied to in.
Definition: Maps.h:2089
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:2415
Mat3d applyIJC(const Mat3d &m) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:469
void write(std::ostream &os) const
write serialization
Definition: Maps.h:1786
void setTranslation(const Vec3< T > &t)
Definition: Mat4.h:319
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:1851
static bool isEqualBase(const MapT &self, const MapBase &other)
Definition: Maps.h:273
bool operator==(const ScaleMap &other) const
Definition: Maps.h:857
const Coord & min() const
Definition: Coord.h:257
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:623
Int32 ValueType
Definition: Coord.h:55
~AffineMap()
Definition: Maps.h:377
#define OPENVDB_VERSION_NAME
Definition: version.h:45
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UnitaryMap.
Definition: Maps.h:1694
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:1154
static void registerMap()
Definition: Maps.h:949
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:2002
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1723
bool isAffine(const Mat4< T > &m)
Definition: Mat4.h:1335
static MapBase::Ptr create()
Return a MapBase::Ptr to a new AffineMap.
Definition: Maps.h:380
boost::shared_ptr< const UniformScaleMap > ConstPtr
Definition: Maps.h:930
bool operator==(const TranslationMap &other) const
Definition: Maps.h:1094
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:761
AffineMap::Ptr getAffineMap() const
Definition: Maps.h:2628
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:382
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:199
CompoundMap< UnitaryMap, TranslationMap > UnitaryAndTranslationMap
Definition: Maps.h:66
std::string str() const
string serialization, useful for debuging
Definition: Maps.h:1085
ScaleMap()
Definition: Maps.h:690
boost::shared_ptr< UnitaryMap > Ptr
Definition: Maps.h:1622
const Vec3d & getInvScaleSqr() const
Return the square of the scale. Used to optimize some finite difference calculations.
Definition: Maps.h:813
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1390
const Vec3d & getInvScale() const
Return 1/(scale)
Definition: Maps.h:1345
void accumPostScale(const Vec3d &v)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:531
double determinant(const Vec3d &) const
Return the product of the scale values, ignores argument.
Definition: Maps.h:1326
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:1821
static bool isRegistered()
Definition: Maps.h:386
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1518
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:1048
UnitaryMap(const UnitaryMap &first, const UnitaryMap &second)
Definition: Maps.h:1687
A specialized linear transform that performs a unitary maping i.e. rotation and or reflection...
Definition: Maps.h:1619
bool isInvertible(const MatType &m)
Determine if a matrix is invertible.
Definition: Mat.h:842
void read(std::istream &is)
read serialization
Definition: Maps.h:1348
void write(std::ostream &os) const
Definition: Maps.h:2652
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:165
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:1290
double determinant() const
Return the determinant of the Jacobian.
Definition: Maps.h:1769
static MapBase::Ptr create()
Return a MapBase::Ptr to a new TranslationMap.
Definition: Maps.h:1012
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to a deep copy of the current AffineMap.
Definition: Maps.h:578
AffineMap::Ptr getAffineMap() const
Return a AffineMap equivalent to this map.
Definition: Maps.h:867
void writeString(std::ostream &os, const Name &name)
Definition: Name.h:58
double determinant() const
Return the determinant of the Jacobian of linear second map.
Definition: Maps.h:2295
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:753
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1760
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:803
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:2450
Mat4d getMat4() const
Return the matrix representation of this AffineMap.
Definition: Maps.h:644
const Vec3d & getScale() const
Returns the scale values.
Definition: Maps.h:1336
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1752
Vec3d applyIJT(const Vec3d &d1_is, const Vec3d &ijk) const
Definition: Maps.h:2184
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1092
const Mat3d & getConstJacobianInv() const
Definition: Maps.h:646
Vec3d voxelSize() const
Return .
Definition: Maps.h:1073
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:484
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:446
bool isIdentity() const
Definition: Maps.h:2611
A specialized Affine transform that scales along the principal axis the scaling is uniform in the thr...
Definition: Maps.h:926
Name type() const
Return UnitaryMap.
Definition: Maps.h:1713
boost::shared_ptr< const NonlinearFrustumMap > ConstPtr
Definition: Maps.h:1877
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:1743
static bool isRegistered()
Definition: Maps.h:1241
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:2084
const BBoxd & getBBox() const
Return the bounding box that defines the frustum in pre-image space.
Definition: Maps.h:2344
bool operator==(const UniformScaleTranslateMap &other) const
Definition: Maps.h:1520
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:1845
void setRow(int i, const Vec3< T > &v)
Set ith row to vector v.
Definition: Mat3.h:157
bool operator==(const ScaleTranslateMap &other) const
Definition: Maps.h:1379
UnitaryMap(const Mat3d &m)
Definition: Maps.h:1644
NonlinearFrustumMap()
Definition: Maps.h:1879
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:1839
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:593
static Name mapType()
Definition: Maps.h:737
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:829
static Name mapType()
Definition: Maps.h:1028
AffineMap::Ptr getAffineMap() const
Definition: Maps.h:2330
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature for the linear second map.
Definition: Maps.h:2220
bool isLinear() const
Return true (a TranslationMap is always linear).
Definition: Maps.h:1031
std::map< Name, MapBase::MapFactory > MapDictionary
Definition: Maps.h:288
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:855
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:1377
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:451
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:465
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:1902
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:790
NonlinearFrustumMap(const NonlinearFrustumMap &other)
Definition: Maps.h:1914
OPENVDB_IMPORT uint32_t getFormatVersion(std::istream &)
Return the file format version number associated with the given input stream.
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1285
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:782
Vec3d voxelSize(const Vec3d &) const
Return .
Definition: Maps.h:1075
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:414
ScaleMap(const ScaleMap &other)
Definition: Maps.h:708
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UniformScaleTranslateMap.
Definition: Maps.h:1492
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:771
MyType & operator=(const MyType &other)
Definition: Maps.h:2603
static bool isRegistered()
Definition: Maps.h:2012
Vec3< double > Vec3d
Definition: Vec3.h:625
CompoundMap(const MyType &other)
Definition: Maps.h:2581
bool operator!=(const UniformScaleMap &other) const
Definition: Maps.h:962
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:2051
static Name mapType()
Return UnitaryMap.
Definition: Maps.h:1715
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of in under the map.
Definition: Maps.h:1736
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:725
const SecondMapType & secondMap() const
Definition: Maps.h:2641
MapBase::Ptr inverseMap() const
Not implemented, since there is currently no map type that can represent the inverse of a frustum...
Definition: Maps.h:2007
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:792
Definition: Exceptions.h:82
bool operator!=(const UniformScaleTranslateMap &other) const
Definition: Maps.h:1524
bool operator!=(const UnitaryMap &other) const
Definition: Maps.h:1732
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:769
~TranslationMap()
Definition: Maps.h:1009
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:444
Vec3d voxelSize() const
Return the size of a voxel at the center of the near plane.
Definition: Maps.h:2307
Abstract base class for maps.
Definition: Maps.h:158
Map traits.
Definition: Maps.h:79
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1014
bool hasUniformScale() const
Return false (by convention true)
Definition: Maps.h:1721
Name type() const
Return the name of this map's concrete type (e.g., "AffineMap").
Definition: Maps.h:395
void setFirstMap(const FirstMapType &first)
Definition: Maps.h:2643
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:1734
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:780
bool isIdentity() const
Return true if the underlying matrix is approximately an identity.
Definition: Maps.h:488
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1494
const Vec3d & getInvScaleSqr() const
Return the square of the scale. Used to optimize some finite difference calculations.
Definition: Maps.h:1341
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:1698
Definition: Exceptions.h:84
void read(std::istream &is)
read serialization
Definition: Maps.h:1780
double determinant(const Vec3d &) const
Return the determinant of the Jacobian, ignores argument.
Definition: Maps.h:1767
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const
Definition: Maps.h:472
TranslationMap()
Definition: Maps.h:1005
double getGamma() const
Definition: Maps.h:2341
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:1441
double determinant() const
Return 1.
Definition: Maps.h:1070
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:1809
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:825
Mat3d applyIJC(const Mat3d &in) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1312
boost::shared_ptr< ScaleMap > Ptr
Definition: Maps.h:687
Name type() const
Return the name of this map's concrete type (e.g., "AffineMap").
Definition: Maps.h:1515
virtual bool isEqual(const MapBase &other) const
Return true if this map is equal to the given map.
Definition: Maps.h:959
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:323
bool operator==(const MyType &other) const
Definition: Maps.h:2593
Vec3< T > row(int i) const
Get ith row, e.g. Vec3d v = m.row(1);.
Definition: Mat3.h:168
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:833
~UniformScaleMap()
Definition: Maps.h:935
static bool isRegistered()
Definition: Maps.h:1503
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:1062
Name type() const
Return the name of this map's concrete type (e.g., "AffineMap").
Definition: Maps.h:956
Mat3d applyIJC(const Mat3d &mat) const
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1064
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
bool isLinear() const
Return true (a ScaleMap is always linear).
Definition: Maps.h:740
boost::shared_ptr< UniformScaleTranslateMap > Ptr
Definition: Maps.h:1479
Axis
Definition: Math.h:767
Vec3< typename MatType::value_type > getScale(const MatType &mat)
Return a Vec3 representing the lengths of the passed matrix's upper 3x3's rows.
Definition: Mat.h:611
bool isDiagonal() const
Definition: Maps.h:2620
bool operator==(const NonlinearFrustumMap &other) const
Definition: Maps.h:2053
bool operator==(const UniformScaleMap &other) const
Definition: Maps.h:961
~ScaleMap()
Definition: Maps.h:718
static bool isRegistered()
Definition: Maps.h:1703
bool hasUniformScale() const
Return true if the values have the same magitude (eg. -1, 1, -1 would be a rotation).
Definition: Maps.h:743
static MapBase::Ptr create()
Return a MapBase::Ptr to a new ScaleTranslateMap.
Definition: Maps.h:1231
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:1434
void write(std::ostream &os) const
write serialization
Definition: Maps.h:1358
void setSecondMap(const SecondMapType &second)
Definition: Maps.h:2644
AffineMap & operator=(const AffineMap &other)
Definition: Maps.h:426
double getDepth() const
Return the unscaled frustm depth.
Definition: Maps.h:2339
bool isLinear() const
Return true (a ScaleTranslateMap is always linear).
Definition: Maps.h:1254
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:455
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:1891
boost::shared_ptr< const TranslationMap > ConstPtr
Definition: Maps.h:1002
boost::shared_ptr< ScaleTranslateMap > Ptr
Definition: Maps.h:1176
Vec3d applyJT(const Vec3d &in) const
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:457
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:467
static bool isRegistered()
Definition: Maps.h:727
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UniformScaleMap.
Definition: Maps.h:938
void write(std::ostream &os) const
write serialization
Definition: Maps.h:557
Name type() const
Return NonlinearFrustumMap.
Definition: Maps.h:2021
MapBase::Ptr inverseMap() const
Return a new map representing the inverse of this map.
Definition: Maps.h:942
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: Coord.h:360
UniformScaleMap(double scale)
Definition: Maps.h:933
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1287
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:776
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:684
Creates the composition of two maps, each of which could be a composition. In the case that each comp...
Definition: Maps.h:66
std::string str() const
string serialization, useful for debugging
Definition: Maps.h:563
ScaleMap(const Vec3d &scale)
Definition: Maps.h:694
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:1406
Name type() const
Definition: Maps.h:2587
boost::shared_ptr< const MyType > ConstPtr
Definition: Maps.h:2571
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
static Name mapType()
Definition: Maps.h:2588
Vec3d applyJT(const Vec3d &in, const Vec3d &) const
Definition: Maps.h:1750
T det() const
Determinant of matrix.
Definition: Mat3.h:481
bool hasSimpleAffine() const
Return true if the second map is a uniform scale, Rotation and translation.
Definition: Maps.h:2353
Vec3d voxelSize() const
Return the absolute values of the scale values.
Definition: Maps.h:1330
void read(std::istream &is)
read serialization
Definition: Maps.h:2356
CompoundMap< SymmetricMap, UnitaryMap > PolarDecomposedMap
Definition: Maps.h:72
double determinant() const
Return the product of the scale values.
Definition: Maps.h:807
OPENVDB_API boost::shared_ptr< MapBase > simplify(boost::shared_ptr< AffineMap > affine)
reduces an AffineMap to a ScaleMap or a ScaleTranslateMap when it can
bool isType() const
Return true if this map is of concrete type MapT (e.g., AffineMap).
Definition: Maps.h:173
Vec3d applyInverseMap(const Vec3d &in) const
Return the pre-image of under the map.
Definition: Maps.h:1276
Tolerance for floating-point comparison.
Definition: Math.h:116
Vec3d applyJacobian(const Vec3d &in) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1740
bool hasTranslation(const Mat4< T > &m)
Definition: Mat4.h:1340
boost::shared_ptr< MapBase > Ptr
Definition: Maps.h:161
CompoundMap()
Definition: Maps.h:2574
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:94
MapBase::Ptr copy() const
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:723
AffineMap(const AffineMap &other)
Definition: Maps.h:358
void write(std::ostream &os) const
write serialization
Definition: Maps.h:838
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:449
Vec3d asVec3d() const
Definition: Coord.h:136
UnitaryMap(const Vec3d &axis, double radians)
Definition: Maps.h:1630
MapBase::Ptr copy() const
Returns a MapBase::Ptr to a deep copy of *this.
Definition: Maps.h:1696
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:1129
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:2445
static void registerMap()
Definition: Maps.h:1243
Name type() const
Return the name of this map's concrete type (e.g., "AffineMap").
Definition: Maps.h:736
bool isDiagonal() const
Return true if the underylying matrix is diagonal.
Definition: Maps.h:490
bool hasUniformScale() const
Return false (by convention true)
Definition: Maps.h:1034
double determinant(const Vec3d &) const
Return 1.
Definition: Maps.h:1068
const Vec3d & getScale() const
Return the scale values that define the map.
Definition: Maps.h:810
SpectralDecomposedMap SymmetricMap
Definition: Maps.h:70
boost::shared_ptr< const AffineMap > ConstPtr
Definition: Maps.h:327
Mat3d applyIJC(const Mat3d &mat, const Vec3d &, const Vec3d &) const
Definition: Maps.h:1065
bool isDiagonal(const MatType &mat)
Determine if a matrix is diagonal.
Definition: Mat.h:875
static void registerMap()
Definition: Maps.h:2014
static Name mapType()
Definition: Maps.h:1516
Vec3d applyIJT(const Vec3d &in) const
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1304
UniformScaleTranslateMap(const UniformScaleMap &scale, const TranslationMap &translate)
Definition: Maps.h:1485
MapBase()
Definition: Maps.h:270
AffineMap(const AffineMap &first, const AffineMap &second)
constructor that merges the matrixes for two affine maps
Definition: Maps.h:371
std::string Name
Definition: Name.h:44
void read(std::istream &is)
read serialization
Definition: Maps.h:550
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const
Return the Jacobian of the map applied to in.
Definition: Maps.h:1041
bool operator==(const UnitaryMap &other) const
Definition: Maps.h:1725
UniformScaleTranslateMap(double scale, const Vec3d &translate)
Definition: Maps.h:1483
UniformScaleTranslateMap()
Definition: Maps.h:1482
TranslationMap(const TranslationMap &other)
Definition: Maps.h:1007
static void registerMap()
Definition: Maps.h:1020
static Name mapType()
Return NonlinearFrustumMap.
Definition: Maps.h:2023
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:2420
bool isIdentity() const
Return true if the map is equivalent to an identity.
Definition: Maps.h:2032
Vec3d applyJT(const Vec3d &in, const Vec3d &isloc) const
Definition: Maps.h:2147
~UniformScaleTranslateMap()
Definition: Maps.h:1489
AffineMap::Ptr getAffineMap() const
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1103
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:1940
UniformScaleMap(const UniformScaleMap &other)
Definition: Maps.h:934
Vec3d applyMap(const Vec3d &in) const
Return the image of in under the map.
Definition: Maps.h:1037