OpenVDB  4.0.1
Maps.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
32 
33 #ifndef OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
34 #define OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
35 
36 #include "Math.h"
37 #include "Mat4.h"
38 #include "Vec3.h"
39 #include "BBox.h"
40 #include "Coord.h"
41 #include <openvdb/io/io.h> // for io::getFormatVersion()
42 #include <openvdb/util/Name.h>
43 #include <openvdb/Types.h>
44 #include <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 
126 
127 
131 
132 
144 
145 
148 
152 
153 
155 
156 
159 {
160 public:
163  using MapFactory = Ptr (*)();
164 
165  MapBase(const MapBase&) = default;
166  virtual ~MapBase() = default;
167 
168  virtual SharedPtr<AffineMap> getAffineMap() const = 0;
169 
171  virtual Name type() const = 0;
172 
174  template<typename MapT> bool isType() const { return this->type() == MapT::mapType(); }
175 
177  virtual bool isEqual(const MapBase& other) const = 0;
178 
180  virtual bool isLinear() const = 0;
182  virtual bool hasUniformScale() const = 0;
183 
184  virtual Vec3d applyMap(const Vec3d& in) const = 0;
185  virtual Vec3d applyInverseMap(const Vec3d& in) const = 0;
186 
188  virtual Vec3d applyIJT(const Vec3d& in) const = 0;
192  virtual Vec3d applyIJT(const Vec3d& in, const Vec3d& domainPos) const = 0;
194 
195  virtual Mat3d applyIJC(const Mat3d& m) const = 0;
196  virtual Mat3d applyIJC(const Mat3d& m, const Vec3d& v, const Vec3d& domainPos) const = 0;
197 
198 
199  virtual double determinant() const = 0;
200  virtual double determinant(const Vec3d&) const = 0;
201 
202 
204  virtual Vec3d voxelSize() const = 0;
208  virtual Vec3d voxelSize(const Vec3d&) const = 0;
210 
211  virtual void read(std::istream&) = 0;
212  virtual void write(std::ostream&) const = 0;
213 
214  virtual std::string str() const = 0;
215 
216  virtual MapBase::Ptr copy() const = 0;
217 
219  virtual MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const = 0;
221  virtual MapBase::Ptr preTranslate(const Vec3d&) const = 0;
222  virtual MapBase::Ptr preScale(const Vec3d&) const = 0;
223  virtual MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const = 0;
224 
225  virtual MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const = 0;
226  virtual MapBase::Ptr postTranslate(const Vec3d&) const = 0;
227  virtual MapBase::Ptr postScale(const Vec3d&) const = 0;
228  virtual MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const = 0;
230 
232  virtual Vec3d applyJacobian(const Vec3d& in) const = 0;
238  virtual Vec3d applyJacobian(const Vec3d& in, const Vec3d& domainPos) const = 0;
240 
242  virtual Vec3d applyInverseJacobian(const Vec3d& in) const = 0;
248  virtual Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d& domainPos) const = 0;
250 
251 
253  virtual Vec3d applyJT(const Vec3d& in) const = 0;
260  virtual Vec3d applyJT(const Vec3d& in, const Vec3d& domainPos) const = 0;
262 
268  virtual MapBase::Ptr inverseMap() const = 0;
269 
270 protected:
271  MapBase() {}
272 
273  template<typename MapT>
274  static bool isEqualBase(const MapT& self, const MapBase& other)
275  {
276  return other.isType<MapT>() && (self == *static_cast<const MapT*>(&other));
277  }
278 };
279 
280 
282 
283 
287 {
288 public:
289  using MapDictionary = std::map<Name, MapBase::MapFactory>;
290 
291  static MapRegistry* instance();
292 
294  static MapBase::Ptr createMap(const Name&);
295 
297  static bool isRegistered(const Name&);
298 
300  static void registerMap(const Name&, MapBase::MapFactory);
301 
303  static void unregisterMap(const Name&);
304 
306  static void clear();
307 
308 private:
309  MapRegistry() {}
310 
311  static MapRegistry* staticInstance();
312 
313  static MapRegistry* mInstance;
314 
315  MapDictionary mMap;
316 };
317 
318 
320 
321 
325 {
326 public:
329 
331  mMatrix(Mat4d::identity()),
332  mMatrixInv(Mat4d::identity()),
333  mJacobianInv(Mat3d::identity()),
334  mDeterminant(1),
335  mVoxelSize(Vec3d(1,1,1)),
336  mIsDiagonal(true),
337  mIsIdentity(true)
338  // the default constructor for translation is zero
339  {
340  }
341 
342  AffineMap(const Mat3d& m)
343  {
344  Mat4d mat4(Mat4d::identity());
345  mat4.setMat3(m);
346  mMatrix = mat4;
347  updateAcceleration();
348  }
349 
350  AffineMap(const Mat4d& m): mMatrix(m)
351  {
352  if (!isAffine(m)) {
354  "Tried to initialize an affine transform from a non-affine 4x4 matrix");
355  }
356  updateAcceleration();
357  }
358 
359  AffineMap(const AffineMap& other):
360  MapBase(other),
361  mMatrix(other.mMatrix),
362  mMatrixInv(other.mMatrixInv),
363  mJacobianInv(other.mJacobianInv),
364  mDeterminant(other.mDeterminant),
365  mVoxelSize(other.mVoxelSize),
366  mIsDiagonal(other.mIsDiagonal),
367  mIsIdentity(other.mIsIdentity)
368  {
369  }
370 
372  AffineMap(const AffineMap& first, const AffineMap& second):
373  mMatrix(first.mMatrix * second.mMatrix)
374  {
375  updateAcceleration();
376  }
377 
378  ~AffineMap() override = default;
379 
381  static MapBase::Ptr create() { return MapBase::Ptr(new AffineMap()); }
383  MapBase::Ptr copy() const override { return MapBase::Ptr(new AffineMap(*this)); }
384 
385  MapBase::Ptr inverseMap() const override { return MapBase::Ptr(new AffineMap(mMatrixInv)); }
386 
387  static bool isRegistered() { return MapRegistry::isRegistered(AffineMap::mapType()); }
388 
389  static void registerMap()
390  {
391  MapRegistry::registerMap(
392  AffineMap::mapType(),
393  AffineMap::create);
394  }
395 
396  Name type() const override { return mapType(); }
397  static Name mapType() { return Name("AffineMap"); }
398 
400  bool isLinear() const override { return true; }
401 
403  bool hasUniformScale() const override
404  {
405  Mat3d mat = mMatrix.getMat3();
406  const double det = mat.det();
407  if (isApproxEqual(det, double(0))) {
408  return false;
409  } else {
410  mat *= (1.0 / pow(std::abs(det), 1.0/3.0));
411  return isUnitary(mat);
412  }
413  }
414 
415  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
416 
417  bool operator==(const AffineMap& other) const
418  {
419  // the Mat.eq() is approximate
420  if (!mMatrix.eq(other.mMatrix)) { return false; }
421  if (!mMatrixInv.eq(other.mMatrixInv)) { return false; }
422  return true;
423  }
424 
425  bool operator!=(const AffineMap& other) const { return !(*this == other); }
426 
428  {
429  mMatrix = other.mMatrix;
430  mMatrixInv = other.mMatrixInv;
431 
432  mJacobianInv = other.mJacobianInv;
433  mDeterminant = other.mDeterminant;
434  mVoxelSize = other.mVoxelSize;
435  mIsDiagonal = other.mIsDiagonal;
436  mIsIdentity = other.mIsIdentity;
437  return *this;
438  }
440  Vec3d applyMap(const Vec3d& in) const override { return in * mMatrix; }
442  Vec3d applyInverseMap(const Vec3d& in) const override {return in * mMatrixInv; }
443 
445  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const override { return applyJacobian(in); }
447  Vec3d applyJacobian(const Vec3d& in) const override { return mMatrix.transform3x3(in); }
448 
451  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const override {
452  return applyInverseJacobian(in);
453  }
456  Vec3d applyInverseJacobian(const Vec3d& in) const override {
457  return mMatrixInv.transform3x3(in);
458  }
459 
462  Vec3d applyJT(const Vec3d& in, const Vec3d&) const override { return applyJT(in); }
464  Vec3d applyJT(const Vec3d& in) const override {
465  const double* m = mMatrix.asPointer();
466  return Vec3d( m[ 0] * in[0] + m[ 1] * in[1] + m[ 2] * in[2],
467  m[ 4] * in[0] + m[ 5] * in[1] + m[ 6] * in[2],
468  m[ 8] * in[0] + m[ 9] * in[1] + m[10] * in[2] );
469  }
470 
472  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const override { return applyIJT(in); }
474  Vec3d applyIJT(const Vec3d& in) const override { return in * mJacobianInv; }
476  Mat3d applyIJC(const Mat3d& m) const override {
477  return mJacobianInv.transpose()* m * mJacobianInv;
478  }
479  Mat3d applyIJC(const Mat3d& in, const Vec3d& , const Vec3d& ) const override {
480  return applyIJC(in);
481  }
483  double determinant(const Vec3d& ) const override { return determinant(); }
485  double determinant() const override { return mDeterminant; }
486 
488  Vec3d voxelSize() const override { return mVoxelSize; }
491  Vec3d voxelSize(const Vec3d&) const override { return voxelSize(); }
493 
495  bool isIdentity() const { return mIsIdentity; }
497  bool isDiagonal() const { return mIsDiagonal; }
499  bool isScale() const { return isDiagonal(); }
501  bool isScaleTranslate() const { return math::isDiagonal(mMatrix.getMat3()); }
502 
503 
504  // Methods that modify the existing affine map
505 
507  void accumPreRotation(Axis axis, double radians)
509  {
510  mMatrix.preRotate(axis, radians);
511  updateAcceleration();
512  }
513  void accumPreScale(const Vec3d& v)
514  {
515  mMatrix.preScale(v);
516  updateAcceleration();
517  }
518  void accumPreTranslation(const Vec3d& v)
519  {
520  mMatrix.preTranslate(v);
521  updateAcceleration();
522  }
523  void accumPreShear(Axis axis0, Axis axis1, double shear)
524  {
525  mMatrix.preShear(axis0, axis1, shear);
526  updateAcceleration();
527  }
529 
530 
532  void accumPostRotation(Axis axis, double radians)
534  {
535  mMatrix.postRotate(axis, radians);
536  updateAcceleration();
537  }
538  void accumPostScale(const Vec3d& v)
539  {
540  mMatrix.postScale(v);
541  updateAcceleration();
542  }
544  {
545  mMatrix.postTranslate(v);
546  updateAcceleration();
547  }
548  void accumPostShear(Axis axis0, Axis axis1, double shear)
549  {
550  mMatrix.postShear(axis0, axis1, shear);
551  updateAcceleration();
552  }
554 
555 
557  void read(std::istream& is) override { mMatrix.read(is); updateAcceleration(); }
559  void write(std::ostream& os) const override { mMatrix.write(os); }
561  std::string str() const override
562  {
563  std::ostringstream buffer;
564  buffer << " - mat4:\n" << mMatrix.str() << std::endl;
565  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
566  return buffer.str();
567  }
568 
571  {
572  return createFullyDecomposedMap(mMatrix);
573  }
574 
576  AffineMap::Ptr getAffineMap() const override { return AffineMap::Ptr(new AffineMap(*this)); }
577 
579  AffineMap::Ptr inverse() const { return AffineMap::Ptr(new AffineMap(mMatrixInv)); }
580 
581 
583  MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const override
586  {
587  AffineMap::Ptr affineMap = getAffineMap();
588  affineMap->accumPreRotation(axis, radians);
589  return simplify(affineMap);
590  }
591  MapBase::Ptr preTranslate(const Vec3d& t) const override
592  {
593  AffineMap::Ptr affineMap = getAffineMap();
594  affineMap->accumPreTranslation(t);
595  return StaticPtrCast<MapBase, AffineMap>(affineMap);
596  }
597  MapBase::Ptr preScale(const Vec3d& s) const override
598  {
599  AffineMap::Ptr affineMap = getAffineMap();
600  affineMap->accumPreScale(s);
601  return StaticPtrCast<MapBase, AffineMap>(affineMap);
602  }
603  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
604  {
605  AffineMap::Ptr affineMap = getAffineMap();
606  affineMap->accumPreShear(axis0, axis1, shear);
607  return simplify(affineMap);
608  }
610 
611 
613  MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const override
616  {
617  AffineMap::Ptr affineMap = getAffineMap();
618  affineMap->accumPostRotation(axis, radians);
619  return simplify(affineMap);
620  }
621  MapBase::Ptr postTranslate(const Vec3d& t) const override
622  {
623  AffineMap::Ptr affineMap = getAffineMap();
624  affineMap->accumPostTranslation(t);
625  return StaticPtrCast<MapBase, AffineMap>(affineMap);
626  }
627  MapBase::Ptr postScale(const Vec3d& s) const override
628  {
629  AffineMap::Ptr affineMap = getAffineMap();
630  affineMap->accumPostScale(s);
631  return StaticPtrCast<MapBase, AffineMap>(affineMap);
632  }
633  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
634  {
635  AffineMap::Ptr affineMap = getAffineMap();
636  affineMap->accumPostShear(axis0, axis1, shear);
637  return simplify(affineMap);
638  }
640 
642  Mat4d getMat4() const { return mMatrix;}
643  const Mat4d& getConstMat4() const {return mMatrix;}
644  const Mat3d& getConstJacobianInv() const {return mJacobianInv;}
645 
646 private:
647  void updateAcceleration() {
648  Mat3d mat3 = mMatrix.getMat3();
649  mDeterminant = mat3.det();
650 
651  if (std::abs(mDeterminant) < (3.0 * math::Tolerance<double>::value())) {
653  "Tried to initialize an affine transform from a nearly singular matrix");
654  }
655  mMatrixInv = mMatrix.inverse();
656  mJacobianInv = mat3.inverse().transpose();
657  mIsDiagonal = math::isDiagonal(mMatrix);
658  mIsIdentity = math::isIdentity(mMatrix);
659  Vec3d pos = applyMap(Vec3d(0,0,0));
660  mVoxelSize(0) = (applyMap(Vec3d(1,0,0)) - pos).length();
661  mVoxelSize(1) = (applyMap(Vec3d(0,1,0)) - pos).length();
662  mVoxelSize(2) = (applyMap(Vec3d(0,0,1)) - pos).length();
663  }
664 
665  // the underlying matrix
666  Mat4d mMatrix;
667 
668  // stored for acceleration
669  Mat4d mMatrixInv;
670  Mat3d mJacobianInv;
671  double mDeterminant;
672  Vec3d mVoxelSize;
673  bool mIsDiagonal, mIsIdentity;
674 }; // class AffineMap
675 
676 
678 
679 
683 {
684 public:
687 
688  ScaleMap(): MapBase(), mScaleValues(Vec3d(1,1,1)), mVoxelSize(Vec3d(1,1,1)),
689  mScaleValuesInverse(Vec3d(1,1,1)),
690  mInvScaleSqr(1,1,1), mInvTwiceScale(0.5,0.5,0.5){}
691 
693  MapBase(),
694  mScaleValues(scale),
695  mVoxelSize(Vec3d(std::abs(scale(0)),std::abs(scale(1)), std::abs(scale(2))))
696  {
697  double determinant = scale[0]* scale[1] * scale[2];
698  if (std::abs(determinant) < 3.0 * math::Tolerance<double>::value()) {
699  OPENVDB_THROW(ArithmeticError, "Non-zero scale values required");
700  }
701  mScaleValuesInverse = 1.0 / mScaleValues;
702  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
703  mInvTwiceScale = mScaleValuesInverse / 2;
704  }
705 
706  ScaleMap(const ScaleMap& other):
707  MapBase(),
708  mScaleValues(other.mScaleValues),
709  mVoxelSize(other.mVoxelSize),
710  mScaleValuesInverse(other.mScaleValuesInverse),
711  mInvScaleSqr(other.mInvScaleSqr),
712  mInvTwiceScale(other.mInvTwiceScale)
713  {
714  }
715 
716  ~ScaleMap() override = default;
717 
719  static MapBase::Ptr create() { return MapBase::Ptr(new ScaleMap()); }
721  MapBase::Ptr copy() const override { return MapBase::Ptr(new ScaleMap(*this)); }
722 
723  MapBase::Ptr inverseMap() const override {
724  return MapBase::Ptr(new ScaleMap(mScaleValuesInverse));
725  }
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 override { return mapType(); }
737  static Name mapType() { return Name("ScaleMap"); }
738 
740  bool isLinear() const override { return true; }
741 
743  bool hasUniformScale() const override
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 override
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 override
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 override { return applyJacobian(in); }
771  Vec3d applyJacobian(const Vec3d& in) const override { return applyMap(in); }
772 
775  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const override {
776  return applyInverseJacobian(in);
777  }
780  Vec3d applyInverseJacobian(const Vec3d& in) const override { return applyInverseMap(in); }
781 
784  Vec3d applyJT(const Vec3d& in, const Vec3d&) const override { return applyJT(in); }
786  Vec3d applyJT(const Vec3d& in) const override { return applyMap(in); }
787 
790  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const override { return applyIJT(in);}
792  Vec3d applyIJT(const Vec3d& in) const override { return applyInverseMap(in); }
794  Mat3d applyIJC(const Mat3d& in) const override
795  {
796  Mat3d tmp;
797  for (int i = 0; i < 3; i++) {
798  tmp.setRow(i, in.row(i) * mScaleValuesInverse(i));
799  }
800  for (int i = 0; i < 3; i++) {
801  tmp.setCol(i, tmp.col(i) * mScaleValuesInverse(i));
802  }
803  return tmp;
804  }
805  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d&) const override {
806  return applyIJC(in);
807  }
809  double determinant(const Vec3d&) const override { return determinant(); }
811  double determinant() const override {
812  return mScaleValues.x() * mScaleValues.y() * mScaleValues.z();
813  }
814 
816  const Vec3d& getScale() const {return mScaleValues;}
817 
819  const Vec3d& getInvScaleSqr() const { return mInvScaleSqr; }
821  const Vec3d& getInvTwiceScale() const { return mInvTwiceScale; }
823  const Vec3d& getInvScale() const { return mScaleValuesInverse; }
824 
826  Vec3d voxelSize() const override { return mVoxelSize; }
830  Vec3d voxelSize(const Vec3d&) const override { return voxelSize(); }
832 
834  void read(std::istream& is) override
835  {
836  mScaleValues.read(is);
837  mVoxelSize.read(is);
838  mScaleValuesInverse.read(is);
839  mInvScaleSqr.read(is);
840  mInvTwiceScale.read(is);
841  }
843  void write(std::ostream& os) const override
844  {
845  mScaleValues.write(os);
846  mVoxelSize.write(os);
847  mScaleValuesInverse.write(os);
848  mInvScaleSqr.write(os);
849  mInvTwiceScale.write(os);
850  }
852  std::string str() const override
853  {
854  std::ostringstream buffer;
855  buffer << " - scale: " << mScaleValues << std::endl;
856  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
857  return buffer.str();
858  }
859 
860  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
861 
862  bool operator==(const ScaleMap& other) const
863  {
864  // ::eq() uses a tolerance
865  if (!mScaleValues.eq(other.mScaleValues)) { return false; }
866  return true;
867  }
868 
869  bool operator!=(const ScaleMap& other) const { return !(*this == other); }
870 
872  AffineMap::Ptr getAffineMap() const override
873  {
874  return AffineMap::Ptr(new AffineMap(math::scale<Mat4d>(mScaleValues)));
875  }
876 
877 
878 
880  MapBase::Ptr preRotate(double radians, Axis axis) const override
883  {
884  AffineMap::Ptr affineMap = getAffineMap();
885  affineMap->accumPreRotation(axis, radians);
886  return simplify(affineMap);
887  }
888 
889  MapBase::Ptr preTranslate(const Vec3d&) const override;
890  MapBase::Ptr preScale(const Vec3d&) const override;
891  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
892  {
893  AffineMap::Ptr affineMap = getAffineMap();
894  affineMap->accumPreShear(axis0, axis1, shear);
895  return simplify(affineMap);
896  }
898 
899 
901  MapBase::Ptr postRotate(double radians, Axis axis) const override
904  {
905  AffineMap::Ptr affineMap = getAffineMap();
906  affineMap->accumPostRotation(axis, radians);
907  return simplify(affineMap);
908  }
909  MapBase::Ptr postTranslate(const Vec3d&) const override;
910  MapBase::Ptr postScale(const Vec3d&) const override;
911  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
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:
931 
933  UniformScaleMap(double scale): ScaleMap(Vec3d(scale, scale, scale)) {}
934  UniformScaleMap(const UniformScaleMap& other): ScaleMap(other) {}
935  ~UniformScaleMap() override = default;
936 
938  static MapBase::Ptr create() { return MapBase::Ptr(new UniformScaleMap()); }
940  MapBase::Ptr copy() const override { return MapBase::Ptr(new UniformScaleMap(*this)); }
941 
942  MapBase::Ptr inverseMap() const override
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 override { return mapType(); }
957  static Name mapType() { return Name("UniformScaleMap"); }
958 
959  bool isEqual(const MapBase& other) const override { 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&) const override;
967 
970  MapBase::Ptr postTranslate(const Vec3d&) const override;
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:
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 
1009  ~TranslationMap() override = default;
1010 
1012  static MapBase::Ptr create() { return MapBase::Ptr(new TranslationMap()); }
1014  MapBase::Ptr copy() const override { return MapBase::Ptr(new TranslationMap(*this)); }
1015 
1016  MapBase::Ptr inverseMap() const override {
1017  return MapBase::Ptr(new TranslationMap(-mTranslation));
1018  }
1019 
1020  static bool isRegistered() { return MapRegistry::isRegistered(TranslationMap::mapType()); }
1021 
1022  static void registerMap()
1023  {
1024  MapRegistry::registerMap(
1025  TranslationMap::mapType(),
1026  TranslationMap::create);
1027  }
1028 
1029  Name type() const override { return mapType(); }
1030  static Name mapType() { return Name("TranslationMap"); }
1031 
1033  bool isLinear() const override { return true; }
1034 
1036  bool hasUniformScale() const override { return true; }
1037 
1039  Vec3d applyMap(const Vec3d& in) const override { return in + mTranslation; }
1041  Vec3d applyInverseMap(const Vec3d& in) const override { return in - mTranslation; }
1043  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const override { return applyJacobian(in); }
1045  Vec3d applyJacobian(const Vec3d& in) const override { return in; }
1046 
1049  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const override {
1050  return applyInverseJacobian(in);
1051  }
1054  Vec3d applyInverseJacobian(const Vec3d& in) const override { return in; }
1055 
1056 
1059  Vec3d applyJT(const Vec3d& in, const Vec3d&) const override { return applyJT(in); }
1061  Vec3d applyJT(const Vec3d& in) const override { return in; }
1062 
1065  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const override { return applyIJT(in);}
1068  Vec3d applyIJT(const Vec3d& in) const override {return in;}
1070  Mat3d applyIJC(const Mat3d& mat) const override {return mat;}
1071  Mat3d applyIJC(const Mat3d& mat, const Vec3d&, const Vec3d&) const override {
1072  return applyIJC(mat);
1073  }
1074 
1076  double determinant(const Vec3d& ) const override { return determinant(); }
1078  double determinant() const override { return 1.0; }
1079 
1081  Vec3d voxelSize() const override { return Vec3d(1,1,1);}
1083  Vec3d voxelSize(const Vec3d&) const override { return voxelSize();}
1084 
1086  const Vec3d& getTranslation() const { return mTranslation; }
1087 
1089  void read(std::istream& is) override { mTranslation.read(is); }
1091  void write(std::ostream& os) const override { mTranslation.write(os); }
1093  std::string str() const override
1094  {
1095  std::ostringstream buffer;
1096  buffer << " - translation: " << mTranslation << std::endl;
1097  return buffer.str();
1098  }
1099 
1100  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
1101 
1102  bool operator==(const TranslationMap& other) const
1103  {
1104  // ::eq() uses a tolerance
1105  return mTranslation.eq(other.mTranslation);
1106  }
1107 
1108  bool operator!=(const TranslationMap& other) const { return !(*this == other); }
1109 
1111  AffineMap::Ptr getAffineMap() const override
1112  {
1113  Mat4d matrix(Mat4d::identity());
1114  matrix.setTranslation(mTranslation);
1115 
1116  AffineMap::Ptr affineMap(new AffineMap(matrix));
1117  return affineMap;
1118  }
1119 
1121  MapBase::Ptr preRotate(double radians, Axis axis) const override
1124  {
1125  AffineMap::Ptr affineMap = getAffineMap();
1126  affineMap->accumPreRotation(axis, radians);
1127  return simplify(affineMap);
1128 
1129  }
1130  MapBase::Ptr preTranslate(const Vec3d& t) const override
1131  {
1132  return MapBase::Ptr(new TranslationMap(t + mTranslation));
1133  }
1134 
1135  MapBase::Ptr preScale(const Vec3d& v) const override;
1136 
1137  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
1138  {
1139  AffineMap::Ptr affineMap = getAffineMap();
1140  affineMap->accumPreShear(axis0, axis1, shear);
1141  return simplify(affineMap);
1142  }
1144 
1146  MapBase::Ptr postRotate(double radians, Axis axis) const override
1149  {
1150  AffineMap::Ptr affineMap = getAffineMap();
1151  affineMap->accumPostRotation(axis, radians);
1152  return simplify(affineMap);
1153 
1154  }
1155  MapBase::Ptr postTranslate(const Vec3d& t) const override
1156  { // post and pre are the same for this
1157  return MapBase::Ptr(new TranslationMap(t + mTranslation));
1158  }
1159 
1160  MapBase::Ptr postScale(const Vec3d& v) const override;
1161 
1162  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
1163  {
1164  AffineMap::Ptr affineMap = getAffineMap();
1165  affineMap->accumPostShear(axis0, axis1, shear);
1166  return simplify(affineMap);
1167  }
1169 
1170 private:
1171  Vec3d mTranslation;
1172 }; // class TranslationMap
1173 
1174 
1176 
1177 
1182 {
1183 public:
1186 
1188  MapBase(),
1189  mTranslation(Vec3d(0,0,0)),
1190  mScaleValues(Vec3d(1,1,1)),
1191  mVoxelSize(Vec3d(1,1,1)),
1192  mScaleValuesInverse(Vec3d(1,1,1)),
1193  mInvScaleSqr(1,1,1),
1194  mInvTwiceScale(0.5,0.5,0.5)
1195  {
1196  }
1197 
1198  ScaleTranslateMap(const Vec3d& scale, const Vec3d& translate):
1199  MapBase(),
1200  mTranslation(translate),
1201  mScaleValues(scale),
1202  mVoxelSize(std::abs(scale(0)), std::abs(scale(1)), std::abs(scale(2)))
1203  {
1204  const double determinant = scale[0]* scale[1] * scale[2];
1205  if (std::abs(determinant) < 3.0 * math::Tolerance<double>::value()) {
1206  OPENVDB_THROW(ArithmeticError, "Non-zero scale values required");
1207  }
1208  mScaleValuesInverse = 1.0 / mScaleValues;
1209  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
1210  mInvTwiceScale = mScaleValuesInverse / 2;
1211  }
1212 
1213  ScaleTranslateMap(const ScaleMap& scale, const TranslationMap& translate):
1214  MapBase(),
1215  mTranslation(translate.getTranslation()),
1216  mScaleValues(scale.getScale()),
1217  mVoxelSize(std::abs(mScaleValues(0)),
1218  std::abs(mScaleValues(1)),
1219  std::abs(mScaleValues(2))),
1220  mScaleValuesInverse(1.0 / scale.getScale())
1221  {
1222  mInvScaleSqr = mScaleValuesInverse * mScaleValuesInverse;
1223  mInvTwiceScale = mScaleValuesInverse / 2;
1224  }
1225 
1227  MapBase(),
1228  mTranslation(other.mTranslation),
1229  mScaleValues(other.mScaleValues),
1230  mVoxelSize(other.mVoxelSize),
1231  mScaleValuesInverse(other.mScaleValuesInverse),
1232  mInvScaleSqr(other.mInvScaleSqr),
1233  mInvTwiceScale(other.mInvTwiceScale)
1234  {}
1235 
1236  ~ScaleTranslateMap() override = default;
1237 
1241  MapBase::Ptr copy() const override { return MapBase::Ptr(new ScaleTranslateMap(*this)); }
1242 
1243  MapBase::Ptr inverseMap() const override
1244  {
1245  return MapBase::Ptr(new ScaleTranslateMap(
1246  mScaleValuesInverse, -mScaleValuesInverse * mTranslation));
1247  }
1248 
1249  static bool isRegistered() { return MapRegistry::isRegistered(ScaleTranslateMap::mapType()); }
1250 
1251  static void registerMap()
1252  {
1253  MapRegistry::registerMap(
1254  ScaleTranslateMap::mapType(),
1255  ScaleTranslateMap::create);
1256  }
1257 
1258  Name type() const override { return mapType(); }
1259  static Name mapType() { return Name("ScaleTranslateMap"); }
1260 
1262  bool isLinear() const override { return true; }
1263 
1266  bool hasUniformScale() const override
1267  {
1268  bool value = isApproxEqual(
1269  std::abs(mScaleValues.x()), std::abs(mScaleValues.y()), double(5e-7));
1270  value = value && isApproxEqual(
1271  std::abs(mScaleValues.x()), std::abs(mScaleValues.z()), double(5e-7));
1272  return value;
1273  }
1274 
1276  Vec3d applyMap(const Vec3d& in) const override
1277  {
1278  return Vec3d(
1279  in.x() * mScaleValues.x() + mTranslation.x(),
1280  in.y() * mScaleValues.y() + mTranslation.y(),
1281  in.z() * mScaleValues.z() + mTranslation.z());
1282  }
1284  Vec3d applyInverseMap(const Vec3d& in) const override
1285  {
1286  return Vec3d(
1287  (in.x() - mTranslation.x() ) * mScaleValuesInverse.x(),
1288  (in.y() - mTranslation.y() ) * mScaleValuesInverse.y(),
1289  (in.z() - mTranslation.z() ) * mScaleValuesInverse.z());
1290  }
1291 
1293  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const override { return applyJacobian(in); }
1295  Vec3d applyJacobian(const Vec3d& in) const override { return in * mScaleValues; }
1296 
1299  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const override { return applyInverseJacobian(in); }
1302  Vec3d applyInverseJacobian(const Vec3d& in) const override { return in * mScaleValuesInverse; }
1303 
1306  Vec3d applyJT(const Vec3d& in, const Vec3d&) const override { return applyJT(in); }
1308  Vec3d applyJT(const Vec3d& in) const override { return applyJacobian(in); }
1309 
1312  Vec3d applyIJT(const Vec3d& in, const Vec3d&) const override { return applyIJT(in);}
1314  Vec3d applyIJT(const Vec3d& in) const override
1315  {
1316  return Vec3d(
1317  in.x() * mScaleValuesInverse.x(),
1318  in.y() * mScaleValuesInverse.y(),
1319  in.z() * mScaleValuesInverse.z());
1320  }
1322  Mat3d applyIJC(const Mat3d& in) const override
1323  {
1324  Mat3d tmp;
1325  for (int i=0; i<3; i++){
1326  tmp.setRow(i, in.row(i)*mScaleValuesInverse(i));
1327  }
1328  for (int i=0; i<3; i++){
1329  tmp.setCol(i, tmp.col(i)*mScaleValuesInverse(i));
1330  }
1331  return tmp;
1332  }
1333  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d& ) const override {
1334  return applyIJC(in);
1335  }
1336 
1338  double determinant(const Vec3d&) const override { return determinant(); }
1340  double determinant() const override {
1341  return mScaleValues.x() * mScaleValues.y() * mScaleValues.z();
1342  }
1344  Vec3d voxelSize() const override { return mVoxelSize;}
1346  Vec3d voxelSize(const Vec3d&) const override { return voxelSize();}
1347 
1349  const Vec3d& getScale() const { return mScaleValues; }
1351  const Vec3d& getTranslation() const { return mTranslation; }
1352 
1354  const Vec3d& getInvScaleSqr() const {return mInvScaleSqr;}
1356  const Vec3d& getInvTwiceScale() const {return mInvTwiceScale;}
1358  const Vec3d& getInvScale() const {return mScaleValuesInverse; }
1359 
1361  void read(std::istream& is) override
1362  {
1363  mTranslation.read(is);
1364  mScaleValues.read(is);
1365  mVoxelSize.read(is);
1366  mScaleValuesInverse.read(is);
1367  mInvScaleSqr.read(is);
1368  mInvTwiceScale.read(is);
1369  }
1371  void write(std::ostream& os) const override
1372  {
1373  mTranslation.write(os);
1374  mScaleValues.write(os);
1375  mVoxelSize.write(os);
1376  mScaleValuesInverse.write(os);
1377  mInvScaleSqr.write(os);
1378  mInvTwiceScale.write(os);
1379  }
1381  std::string str() const override
1382  {
1383  std::ostringstream buffer;
1384  buffer << " - translation: " << mTranslation << std::endl;
1385  buffer << " - scale: " << mScaleValues << std::endl;
1386  buffer << " - voxel dimensions: " << mVoxelSize << std::endl;
1387  return buffer.str();
1388  }
1389 
1390  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
1391 
1392  bool operator==(const ScaleTranslateMap& other) const
1393  {
1394  // ::eq() uses a tolerance
1395  if (!mScaleValues.eq(other.mScaleValues)) { return false; }
1396  if (!mTranslation.eq(other.mTranslation)) { return false; }
1397  return true;
1398  }
1399 
1400  bool operator!=(const ScaleTranslateMap& other) const { return !(*this == other); }
1401 
1403  AffineMap::Ptr getAffineMap() const override
1404  {
1405  AffineMap::Ptr affineMap(new AffineMap(math::scale<Mat4d>(mScaleValues)));
1406  affineMap->accumPostTranslation(mTranslation);
1407  return affineMap;
1408  }
1409 
1411  MapBase::Ptr preRotate(double radians, Axis axis) const override
1414  {
1415  AffineMap::Ptr affineMap = getAffineMap();
1416  affineMap->accumPreRotation(axis, radians);
1417  return simplify(affineMap);
1418  }
1419  MapBase::Ptr preTranslate(const Vec3d& t) const override
1420  {
1421  const Vec3d& s = mScaleValues;
1422  const Vec3d scaled_trans( t.x() * s.x(),
1423  t.y() * s.y(),
1424  t.z() * s.z() );
1425  return MapBase::Ptr( new ScaleTranslateMap(mScaleValues, mTranslation + scaled_trans));
1426  }
1427 
1428  MapBase::Ptr preScale(const Vec3d& v) const override;
1429 
1430  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
1431  {
1432  AffineMap::Ptr affineMap = getAffineMap();
1433  affineMap->accumPreShear(axis0, axis1, shear);
1434  return simplify(affineMap);
1435  }
1437 
1439  MapBase::Ptr postRotate(double radians, Axis axis) const override
1442  {
1443  AffineMap::Ptr affineMap = getAffineMap();
1444  affineMap->accumPostRotation(axis, radians);
1445  return simplify(affineMap);
1446  }
1447  MapBase::Ptr postTranslate(const Vec3d& t) const override
1448  {
1449  return MapBase::Ptr( new ScaleTranslateMap(mScaleValues, mTranslation + t));
1450  }
1451 
1452  MapBase::Ptr postScale(const Vec3d& v) const override;
1453 
1454  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
1455  {
1456  AffineMap::Ptr affineMap = getAffineMap();
1457  affineMap->accumPostShear(axis0, axis1, shear);
1458  return simplify(affineMap);
1459  }
1461 
1462 private:
1463  Vec3d mTranslation, mScaleValues, mVoxelSize, mScaleValuesInverse,
1464  mInvScaleSqr, mInvTwiceScale;
1465 }; // class ScaleTanslateMap
1466 
1467 
1468 inline MapBase::Ptr
1469 ScaleMap::postTranslate(const Vec3d& t) const
1470 {
1471  return MapBase::Ptr(new ScaleTranslateMap(mScaleValues, t));
1472 }
1473 
1474 
1475 inline MapBase::Ptr
1476 ScaleMap::preTranslate(const Vec3d& t) const
1477 {
1478 
1479  const Vec3d& s = mScaleValues;
1480  const Vec3d scaled_trans( t.x() * s.x(),
1481  t.y() * s.y(),
1482  t.z() * s.z() );
1483  return MapBase::Ptr(new ScaleTranslateMap(mScaleValues, scaled_trans));
1484 }
1485 
1486 
1490 {
1491 public:
1494 
1496  UniformScaleTranslateMap(double scale, const Vec3d& translate):
1497  ScaleTranslateMap(Vec3d(scale,scale,scale), translate) {}
1499  ScaleTranslateMap(scale.getScale(), translate.getTranslation()) {}
1500 
1502  ~UniformScaleTranslateMap() override = default;
1503 
1507  MapBase::Ptr copy() const override { return MapBase::Ptr(new UniformScaleTranslateMap(*this)); }
1508 
1509  MapBase::Ptr inverseMap() const override
1510  {
1511  const Vec3d& scaleInv = getInvScale();
1512  const Vec3d& trans = getTranslation();
1513  return MapBase::Ptr(new UniformScaleTranslateMap(scaleInv[0], -scaleInv[0] * trans));
1514  }
1515 
1516  static bool isRegistered()
1517  {
1518  return MapRegistry::isRegistered(UniformScaleTranslateMap::mapType());
1519  }
1520 
1521  static void registerMap()
1522  {
1523  MapRegistry::registerMap(
1524  UniformScaleTranslateMap::mapType(), UniformScaleTranslateMap::create);
1525  }
1526 
1527  Name type() const override { return mapType(); }
1528  static Name mapType() { return Name("UniformScaleTranslateMap"); }
1529 
1530  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
1531 
1532  bool operator==(const UniformScaleTranslateMap& other) const
1533  {
1534  return ScaleTranslateMap::operator==(other);
1535  }
1536  bool operator!=(const UniformScaleTranslateMap& other) const { return !(*this == other); }
1537 
1540  MapBase::Ptr preTranslate(const Vec3d& t) const override
1541  {
1542  const double scale = this->getScale().x();
1543  const Vec3d new_trans = this->getTranslation() + scale * t;
1544  return MapBase::Ptr( new UniformScaleTranslateMap(scale, new_trans));
1545  }
1546 
1549  MapBase::Ptr postTranslate(const Vec3d& t) const override
1550  {
1551  const double scale = this->getScale().x();
1552  return MapBase::Ptr( new UniformScaleTranslateMap(scale, this->getTranslation() + t));
1553  }
1554 }; // class UniformScaleTanslateMap
1555 
1556 
1557 inline MapBase::Ptr
1558 UniformScaleMap::postTranslate(const Vec3d& t) const
1559 {
1560  const double scale = this->getScale().x();
1561  return MapBase::Ptr(new UniformScaleTranslateMap(scale, t));
1562 }
1563 
1564 
1565 inline MapBase::Ptr
1566 UniformScaleMap::preTranslate(const Vec3d& t) const
1567 {
1568  const double scale = this->getScale().x();
1569  return MapBase::Ptr(new UniformScaleTranslateMap(scale, scale*t));
1570 }
1571 
1572 
1573 inline MapBase::Ptr
1574 TranslationMap::preScale(const Vec3d& v) const
1575 {
1576  if (isApproxEqual(v[0],v[1]) && isApproxEqual(v[0],v[2])) {
1577  return MapBase::Ptr(new UniformScaleTranslateMap(v[0], mTranslation));
1578  } else {
1579  return MapBase::Ptr(new ScaleTranslateMap(v, mTranslation));
1580  }
1581 }
1582 
1583 
1584 inline MapBase::Ptr
1585 TranslationMap::postScale(const Vec3d& v) const
1586 {
1587  if (isApproxEqual(v[0],v[1]) && isApproxEqual(v[0],v[2])) {
1588  return MapBase::Ptr(new UniformScaleTranslateMap(v[0], v[0]*mTranslation));
1589  } else {
1590  const Vec3d trans(mTranslation.x()*v.x(),
1591  mTranslation.y()*v.y(),
1592  mTranslation.z()*v.z());
1593  return MapBase::Ptr(new ScaleTranslateMap(v, trans));
1594  }
1595 }
1596 
1597 
1598 inline MapBase::Ptr
1599 ScaleTranslateMap::preScale(const Vec3d& v) const
1600 {
1601  const Vec3d new_scale( v * mScaleValues );
1602  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
1603  return MapBase::Ptr( new UniformScaleTranslateMap(new_scale[0], mTranslation));
1604  } else {
1605  return MapBase::Ptr( new ScaleTranslateMap(new_scale, mTranslation));
1606  }
1607 }
1608 
1609 
1610 inline MapBase::Ptr
1611 ScaleTranslateMap::postScale(const Vec3d& v) const
1612 {
1613  const Vec3d new_scale( v * mScaleValues );
1614  const Vec3d new_trans( mTranslation.x()*v.x(),
1615  mTranslation.y()*v.y(),
1616  mTranslation.z()*v.z() );
1617 
1618  if (isApproxEqual(new_scale[0],new_scale[1]) && isApproxEqual(new_scale[0],new_scale[2])) {
1619  return MapBase::Ptr( new UniformScaleTranslateMap(new_scale[0], new_trans));
1620  } else {
1621  return MapBase::Ptr( new ScaleTranslateMap(new_scale, new_trans));
1622  }
1623 }
1624 
1625 
1627 
1628 
1631 class OPENVDB_API UnitaryMap: public MapBase
1632 {
1633 public:
1636 
1638  UnitaryMap(): mAffineMap(Mat4d::identity())
1639  {
1640  }
1641 
1642  UnitaryMap(const Vec3d& axis, double radians)
1643  {
1644  Mat3d matrix;
1645  matrix.setToRotation(axis, radians);
1646  mAffineMap = AffineMap(matrix);
1647  }
1648 
1649  UnitaryMap(Axis axis, double radians)
1650  {
1651  Mat4d matrix;
1652  matrix.setToRotation(axis, radians);
1653  mAffineMap = AffineMap(matrix);
1654  }
1655 
1656  UnitaryMap(const Mat3d& m)
1657  {
1658  // test that the mat3 is a rotation || reflection
1659  if (!isUnitary(m)) {
1660  OPENVDB_THROW(ArithmeticError, "Matrix initializing unitary map was not unitary");
1661  }
1662 
1663  Mat4d matrix(Mat4d::identity());
1664  matrix.setMat3(m);
1665  mAffineMap = AffineMap(matrix);
1666  }
1667 
1668  UnitaryMap(const Mat4d& m)
1669  {
1670  if (!isInvertible(m)) {
1672  "4x4 Matrix initializing unitary map was not unitary: not invertible");
1673  }
1674 
1675  if (!isAffine(m)) {
1677  "4x4 Matrix initializing unitary map was not unitary: not affine");
1678  }
1679 
1680  if (hasTranslation(m)) {
1682  "4x4 Matrix initializing unitary map was not unitary: had translation");
1683  }
1684 
1685  if (!isUnitary(m.getMat3())) {
1687  "4x4 Matrix initializing unitary map was not unitary");
1688  }
1689 
1690  mAffineMap = AffineMap(m);
1691  }
1692 
1693  UnitaryMap(const UnitaryMap& other):
1694  MapBase(other),
1695  mAffineMap(other.mAffineMap)
1696  {
1697  }
1698 
1699  UnitaryMap(const UnitaryMap& first, const UnitaryMap& second):
1700  mAffineMap(*(first.getAffineMap()), *(second.getAffineMap()))
1701  {
1702  }
1703 
1704  ~UnitaryMap() override = default;
1705 
1707  static MapBase::Ptr create() { return MapBase::Ptr(new UnitaryMap()); }
1709  MapBase::Ptr copy() const override { return MapBase::Ptr(new UnitaryMap(*this)); }
1710 
1711  MapBase::Ptr inverseMap() const override
1712  {
1713  return MapBase::Ptr(new UnitaryMap(mAffineMap.getMat4().inverse()));
1714  }
1715 
1716  static bool isRegistered() { return MapRegistry::isRegistered(UnitaryMap::mapType()); }
1717 
1718  static void registerMap()
1719  {
1720  MapRegistry::registerMap(
1721  UnitaryMap::mapType(),
1722  UnitaryMap::create);
1723  }
1724 
1726  Name type() const override { return mapType(); }
1728  static Name mapType() { return Name("UnitaryMap"); }
1729 
1731  bool isLinear() const override { return true; }
1732 
1734  bool hasUniformScale() const override { return true; }
1735 
1736  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
1737 
1738  bool operator==(const UnitaryMap& other) const
1739  {
1740  // compare underlying linear map.
1741  if (mAffineMap!=other.mAffineMap) return false;
1742  return true;
1743  }
1744 
1745  bool operator!=(const UnitaryMap& other) const { return !(*this == other); }
1747  Vec3d applyMap(const Vec3d& in) const override { return mAffineMap.applyMap(in); }
1749  Vec3d applyInverseMap(const Vec3d& in) const override { return mAffineMap.applyInverseMap(in); }
1750 
1751  Vec3d applyJacobian(const Vec3d& in, const Vec3d&) const override { return applyJacobian(in); }
1753  Vec3d applyJacobian(const Vec3d& in) const override { return mAffineMap.applyJacobian(in); }
1754 
1757  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d&) const override {
1758  return applyInverseJacobian(in);
1759  }
1762  Vec3d applyInverseJacobian(const Vec3d& in) const override {
1763  return mAffineMap.applyInverseJacobian(in);
1764  }
1765 
1768  Vec3d applyJT(const Vec3d& in, const Vec3d&) const override { return applyJT(in); }
1770  Vec3d applyJT(const Vec3d& in) const override {
1771  return applyInverseMap(in); // the transpose of the unitary map is its inverse
1772  }
1773 
1774 
1777  Vec3d applyIJT(const Vec3d& in, const Vec3d& ) const override { return applyIJT(in);}
1779  Vec3d applyIJT(const Vec3d& in) const override { return mAffineMap.applyIJT(in); }
1781  Mat3d applyIJC(const Mat3d& in) const override { return mAffineMap.applyIJC(in); }
1782  Mat3d applyIJC(const Mat3d& in, const Vec3d&, const Vec3d& ) const override {
1783  return applyIJC(in);
1784  }
1785 
1787  double determinant(const Vec3d&) const override { return determinant(); }
1789  double determinant() const override { return mAffineMap.determinant(); }
1790 
1791 
1796  Vec3d voxelSize() const override { return mAffineMap.voxelSize();}
1797  Vec3d voxelSize(const Vec3d&) const override { return voxelSize();}
1798 
1800  void read(std::istream& is) override
1801  {
1802  mAffineMap.read(is);
1803  }
1804 
1806  void write(std::ostream& os) const override
1807  {
1808  mAffineMap.write(os);
1809  }
1811  std::string str() const override
1812  {
1813  std::ostringstream buffer;
1814  buffer << mAffineMap.str();
1815  return buffer.str();
1816  }
1818  AffineMap::Ptr getAffineMap() const override {
1819  return AffineMap::Ptr(new AffineMap(mAffineMap));
1820  }
1821 
1824  MapBase::Ptr preRotate(double radians, Axis axis) const override
1825  {
1826  UnitaryMap first(axis, radians);
1827  UnitaryMap::Ptr unitaryMap(new UnitaryMap(first, *this));
1828  return StaticPtrCast<MapBase, UnitaryMap>(unitaryMap);
1829  }
1832  MapBase::Ptr preTranslate(const Vec3d& t) const override
1833  {
1834  AffineMap::Ptr affineMap = getAffineMap();
1835  affineMap->accumPreTranslation(t);
1836  return simplify(affineMap);
1837  }
1840  MapBase::Ptr preScale(const Vec3d& v) const override
1841  {
1842  AffineMap::Ptr affineMap = getAffineMap();
1843  affineMap->accumPreScale(v);
1844  return simplify(affineMap);
1845  }
1848  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
1849  {
1850  AffineMap::Ptr affineMap = getAffineMap();
1851  affineMap->accumPreShear(axis0, axis1, shear);
1852  return simplify(affineMap);
1853  }
1854 
1857  MapBase::Ptr postRotate(double radians, Axis axis) const override
1858  {
1859  UnitaryMap second(axis, radians);
1860  UnitaryMap::Ptr unitaryMap(new UnitaryMap(*this, second));
1861  return StaticPtrCast<MapBase, UnitaryMap>(unitaryMap);
1862  }
1865  MapBase::Ptr postTranslate(const Vec3d& t) const override
1866  {
1867  AffineMap::Ptr affineMap = getAffineMap();
1868  affineMap->accumPostTranslation(t);
1869  return simplify(affineMap);
1870  }
1873  MapBase::Ptr postScale(const Vec3d& v) const override
1874  {
1875  AffineMap::Ptr affineMap = getAffineMap();
1876  affineMap->accumPostScale(v);
1877  return simplify(affineMap);
1878  }
1881  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
1882  {
1883  AffineMap::Ptr affineMap = getAffineMap();
1884  affineMap->accumPostShear(axis0, axis1, shear);
1885  return simplify(affineMap);
1886  }
1887 
1888 private:
1889  AffineMap mAffineMap;
1890 }; // class UnitaryMap
1891 
1892 
1894 
1895 
1903 {
1904 public:
1907 
1909  MapBase(),
1910  mBBox(Vec3d(0), Vec3d(1)),
1911  mTaper(1),
1912  mDepth(1)
1913  {
1914  init();
1915  }
1916 
1920  NonlinearFrustumMap(const BBoxd& bb, double taper, double depth):
1921  MapBase(),mBBox(bb), mTaper(taper), mDepth(depth)
1922  {
1923  init();
1924  }
1925 
1931  NonlinearFrustumMap(const BBoxd& bb, double taper, double depth,
1932  const MapBase::Ptr& secondMap):
1933  mBBox(bb), mTaper(taper), mDepth(depth)
1934  {
1935  if (!secondMap->isLinear() ) {
1937  "The second map in the Frustum transfrom must be linear");
1938  }
1939  mSecondMap = *( secondMap->getAffineMap() );
1940  init();
1941  }
1942 
1944  MapBase(),
1945  mBBox(other.mBBox),
1946  mTaper(other.mTaper),
1947  mDepth(other.mDepth),
1948  mSecondMap(other.mSecondMap),
1949  mHasSimpleAffine(other.mHasSimpleAffine)
1950  {
1951  init();
1952  }
1953 
1969  NonlinearFrustumMap(const Vec3d& position,
1970  const Vec3d& direction,
1971  const Vec3d& up,
1972  double aspect /* width / height */,
1973  double z_near, double depth,
1974  Coord::ValueType x_count, Coord::ValueType z_count) {
1975 
1979  if (!(depth > 0)) {
1981  "The frustum depth must be non-zero and positive");
1982  }
1983  if (!(up.length() > 0)) {
1985  "The frustum height must be non-zero and positive");
1986  }
1987  if (!(aspect > 0)) {
1989  "The frustum aspect ratio must be non-zero and positive");
1990  }
1991  if (!(isApproxEqual(up.dot(direction), 0.))) {
1993  "The frustum up orientation must be perpendicular to into-frustum direction");
1994  }
1995 
1996  double near_plane_height = 2 * up.length();
1997  double near_plane_width = aspect * near_plane_height;
1998 
1999  Coord::ValueType y_count = static_cast<int>(Round(x_count / aspect));
2000 
2001  mBBox = BBoxd(Vec3d(0,0,0), Vec3d(x_count, y_count, z_count));
2002  mDepth = depth / near_plane_width; // depth non-dimensionalized on width
2003  double gamma = near_plane_width / z_near;
2004  mTaper = 1./(mDepth*gamma + 1.);
2005 
2006  Vec3d direction_unit = direction;
2007  direction_unit.normalize();
2008 
2009  Mat4d r1(Mat4d::identity());
2010  r1.setToRotation(/*from*/Vec3d(0,0,1), /*to */direction_unit);
2011  Mat4d r2(Mat4d::identity());
2012  Vec3d temp = r1.inverse().transform(up);
2013  r2.setToRotation(/*from*/Vec3d(0,1,0), /*to*/temp );
2014  Mat4d scale = math::scale<Mat4d>(
2015  Vec3d(near_plane_width, near_plane_width, near_plane_width));
2016 
2017  // move the near plane to origin, rotate to align with axis, and scale down
2018  // T_inv * R1_inv * R2_inv * scale_inv
2019  Mat4d mat = scale * r2 * r1;
2020  mat.setTranslation(position + z_near*direction_unit);
2021 
2022  mSecondMap = AffineMap(mat);
2023 
2024  init();
2025  }
2026 
2027  ~NonlinearFrustumMap() override = default;
2028 
2032  MapBase::Ptr copy() const override { return MapBase::Ptr(new NonlinearFrustumMap(*this)); }
2033 
2037  MapBase::Ptr inverseMap() const override
2038  {
2040  "inverseMap() is not implemented for NonlinearFrustumMap");
2041  }
2042  static bool isRegistered() { return MapRegistry::isRegistered(NonlinearFrustumMap::mapType()); }
2043 
2044  static void registerMap()
2045  {
2046  MapRegistry::registerMap(
2047  NonlinearFrustumMap::mapType(),
2048  NonlinearFrustumMap::create);
2049  }
2051  Name type() const override { return mapType(); }
2053  static Name mapType() { return Name("NonlinearFrustumMap"); }
2054 
2056  bool isLinear() const override { return false; }
2057 
2059  bool hasUniformScale() const override { return false; }
2060 
2062  bool isIdentity() const
2063  {
2064  // The frustum can only be consistent with a linear map if the taper value is 1
2065  if (!isApproxEqual(mTaper, double(1)) ) return false;
2066 
2067  // There are various ways an identity can decomposed between the two parts of the
2068  // map. Best to just check that the principle vectors are stationary.
2069  const Vec3d e1(1,0,0);
2070  if (!applyMap(e1).eq(e1)) return false;
2071 
2072  const Vec3d e2(0,1,0);
2073  if (!applyMap(e2).eq(e2)) return false;
2074 
2075  const Vec3d e3(0,0,1);
2076  if (!applyMap(e3).eq(e3)) return false;
2077 
2078  return true;
2079  }
2080 
2081  bool isEqual(const MapBase& other) const override { return isEqualBase(*this, other); }
2082 
2083  bool operator==(const NonlinearFrustumMap& other) const
2084  {
2085  if (mBBox!=other.mBBox) return false;
2086  if (!isApproxEqual(mTaper, other.mTaper)) return false;
2087  if (!isApproxEqual(mDepth, other.mDepth)) return false;
2088 
2089  // Two linear transforms are equivalent iff they have the same translation
2090  // and have the same affects on orthongal spanning basis check translation
2091  Vec3d e(0,0,0);
2092  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2094  e(0) = 1;
2095  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2096  e(0) = 0;
2097  e(1) = 1;
2098  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2099  e(1) = 0;
2100  e(2) = 1;
2101  if (!mSecondMap.applyMap(e).eq(other.mSecondMap.applyMap(e))) return false;
2102  return true;
2103  }
2104 
2105  bool operator!=(const NonlinearFrustumMap& other) const { return !(*this == other); }
2106 
2108  Vec3d applyMap(const Vec3d& in) const override
2109  {
2110  return mSecondMap.applyMap(applyFrustumMap(in));
2111  }
2112 
2114  Vec3d applyInverseMap(const Vec3d& in) const override
2115  {
2116  return applyFrustumInverseMap(mSecondMap.applyInverseMap(in));
2117  }
2119  Vec3d applyJacobian(const Vec3d& in) const override { return mSecondMap.applyJacobian(in); }
2121  Vec3d applyJacobian(const Vec3d& in, const Vec3d& isloc) const override
2122  {
2123  // Move the center of the x-face of the bbox
2124  // to the origin in index space.
2125  Vec3d centered(isloc);
2126  centered = centered - mBBox.min();
2127  centered.x() -= mXo;
2128  centered.y() -= mYo;
2129 
2130  // scale the z-direction on depth / K count
2131  const double zprime = centered.z()*mDepthOnLz;
2132 
2133  const double scale = (mGamma * zprime + 1.) / mLx;
2134  const double scale2 = mGamma * mDepthOnLz / mLx;
2135 
2136  const Vec3d tmp(scale * in.x() + scale2 * centered.x()* in.z(),
2137  scale * in.y() + scale2 * centered.y()* in.z(),
2138  mDepthOnLz * in.z());
2139 
2140  return mSecondMap.applyJacobian(tmp);
2141  }
2142 
2143 
2146  Vec3d applyInverseJacobian(const Vec3d& in) const override {
2147  return mSecondMap.applyInverseJacobian(in);
2148  }
2150  Vec3d applyInverseJacobian(const Vec3d& in, const Vec3d& isloc) const override {
2151 
2152  // Move the center of the x-face of the bbox
2153  // to the origin in index space.
2154  Vec3d centered(isloc);
2155  centered = centered - mBBox.min();
2156  centered.x() -= mXo;
2157  centered.y() -= mYo;
2158 
2159  // scale the z-direction on depth / K count
2160  const double zprime = centered.z()*mDepthOnLz;
2161 
2162  const double scale = (mGamma * zprime + 1.) / mLx;
2163  const double scale2 = mGamma * mDepthOnLz / mLx;
2164 
2165 
2166  Vec3d out = mSecondMap.applyInverseJacobian(in);
2167 
2168  out.x() = (out.x() - scale2 * centered.x() * out.z() / mDepthOnLz) / scale;
2169  out.y() = (out.y() - scale2 * centered.y() * out.z() / mDepthOnLz) / scale;
2170  out.z() = out.z() / mDepthOnLz;
2171 
2172  return out;
2173  }
2174 
2177  Vec3d applyJT(const Vec3d& in, const Vec3d& isloc) const override {
2178  const Vec3d tmp = mSecondMap.applyJT(in);
2179  // Move the center of the x-face of the bbox
2180  // to the origin in index space.
2181  Vec3d centered(isloc);
2182  centered = centered - mBBox.min();
2183  centered.x() -= mXo;
2184  centered.y() -= mYo;
2185 
2186  // scale the z-direction on depth / K count
2187  const double zprime = centered.z()*mDepthOnLz;
2188 
2189  const double scale = (mGamma * zprime + 1.) / mLx;
2190  const double scale2 = mGamma * mDepthOnLz / mLx;
2191 
2192  return Vec3d(scale * tmp.x(),
2193  scale * tmp.y(),
2194  scale2 * centered.x()* tmp.x() +
2195  scale2 * centered.y()* tmp.y() +
2196  mDepthOnLz * tmp.z());
2197  }
2199  Vec3d applyJT(const Vec3d& in) const override {
2200  return mSecondMap.applyJT(in);
2201  }
2202 
2204  Vec3d applyIJT(const Vec3d& in) const override { return mSecondMap.applyIJT(in); }
2205 
2206  // the Jacobian of the nonlinear part of the transform is a sparse matrix
2207  // Jacobian^(-T) =
2208  //
2209  // (Lx)( 1/s 0 0 )
2210  // ( 0 1/s 0 )
2211  // ( -(x-xo)g/(sLx) -(y-yo)g/(sLx) Lz/(Depth Lx) )
2214  Vec3d applyIJT(const Vec3d& d1_is, const Vec3d& ijk) const override
2215  {
2216  const Vec3d loc = applyFrustumMap(ijk);
2217  const double s = mGamma * loc.z() + 1.;
2218 
2219  // verify that we aren't at the singularity
2220  if (isApproxEqual(s, 0.)) {
2221  OPENVDB_THROW(ArithmeticError, "Tried to evaluate the frustum transform"
2222  " at the singular focal point (e.g. camera)");
2223  }
2224 
2225  const double sinv = 1.0/s; // 1/(z*gamma + 1)
2226  const double pt0 = mLx * sinv; // Lx / (z*gamma +1)
2227  const double pt1 = mGamma * pt0; // gamma * Lx / ( z*gamma +1)
2228  const double pt2 = pt1 * sinv; // gamma * Lx / ( z*gamma +1)**2
2229 
2230  const Mat3d& jacinv = mSecondMap.getConstJacobianInv();
2231 
2232  // compute \frac{\partial E_i}{\partial x_j}
2233  Mat3d gradE(Mat3d::zero());
2234  for (int j = 0; j < 3; ++j ) {
2235  gradE(0,j) = pt0 * jacinv(0,j) - pt2 * loc.x()*jacinv(2,j);
2236  gradE(1,j) = pt0 * jacinv(1,j) - pt2 * loc.y()*jacinv(2,j);
2237  gradE(2,j) = (1./mDepthOnLz) * jacinv(2,j);
2238  }
2239 
2240  Vec3d result;
2241  for (int i = 0; i < 3; ++i) {
2242  result(i) = d1_is(0) * gradE(0,i) + d1_is(1) * gradE(1,i) + d1_is(2) * gradE(2,i);
2243  }
2244 
2245  return result;
2246 
2247  }
2248 
2250  Mat3d applyIJC(const Mat3d& in) const override { return mSecondMap.applyIJC(in); }
2255  Mat3d applyIJC(const Mat3d& d2_is, const Vec3d& d1_is, const Vec3d& ijk) const override
2256  {
2257  const Vec3d loc = applyFrustumMap(ijk);
2258 
2259  const double s = mGamma * loc.z() + 1.;
2260 
2261  // verify that we aren't at the singularity
2262  if (isApproxEqual(s, 0.)) {
2263  OPENVDB_THROW(ArithmeticError, "Tried to evaluate the frustum transform"
2264  " at the singular focal point (e.g. camera)");
2265  }
2266 
2267  // precompute
2268  const double sinv = 1.0/s; // 1/(z*gamma + 1)
2269  const double pt0 = mLx * sinv; // Lx / (z*gamma +1)
2270  const double pt1 = mGamma * pt0; // gamma * Lx / ( z*gamma +1)
2271  const double pt2 = pt1 * sinv; // gamma * Lx / ( z*gamma +1)**2
2272  const double pt3 = pt2 * sinv; // gamma * Lx / ( z*gamma +1)**3
2273 
2274  const Mat3d& jacinv = mSecondMap.getConstJacobianInv();
2275 
2276  // compute \frac{\partial^2 E_i}{\partial x_j \partial x_k}
2277 
2278  Mat3d matE0(Mat3d::zero());
2279  Mat3d matE1(Mat3d::zero()); // matE2 = 0
2280  for(int j = 0; j < 3; j++) {
2281  for (int k = 0; k < 3; k++) {
2282 
2283  const double pt4 = 2. * jacinv(2,j) * jacinv(2,k) * pt3;
2284 
2285  matE0(j,k) = -(jacinv(0,j) * jacinv(2,k) + jacinv(2,j) * jacinv(0,k)) * pt2 +
2286  pt4 * loc.x();
2287 
2288  matE1(j,k) = -(jacinv(1,j) * jacinv(2,k) + jacinv(2,j) * jacinv(1,k)) * pt2 +
2289  pt4 * loc.y();
2290  }
2291  }
2292 
2293  // compute \frac{\partial E_i}{\partial x_j}
2294  Mat3d gradE(Mat3d::zero());
2295  for (int j = 0; j < 3; ++j ) {
2296  gradE(0,j) = pt0 * jacinv(0,j) - pt2 * loc.x()*jacinv(2,j);
2297  gradE(1,j) = pt0 * jacinv(1,j) - pt2 * loc.y()*jacinv(2,j);
2298  gradE(2,j) = (1./mDepthOnLz) * jacinv(2,j);
2299  }
2300 
2301  Mat3d result(Mat3d::zero());
2302  // compute \fac{\partial E_j}{\partial x_m} \fac{\partial E_i}{\partial x_n}
2303  // \frac{\partial^2 input}{\partial E_i \partial E_j}
2304  for (int m = 0; m < 3; ++m ) {
2305  for ( int n = 0; n < 3; ++n) {
2306  for (int i = 0; i < 3; ++i ) {
2307  for (int j = 0; j < 3; ++j) {
2308  result(m, n) += gradE(j, m) * gradE(i, n) * d2_is(i, j);
2309  }
2310  }
2311  }
2312  }
2313 
2314  for (int m = 0; m < 3; ++m ) {
2315  for ( int n = 0; n < 3; ++n) {
2316  result(m, n) +=
2317  matE0(m, n) * d1_is(0) + matE1(m, n) * d1_is(1);// + matE2(m, n) * d1_is(2);
2318  }
2319  }
2320 
2321  return result;
2322  }
2323 
2325  double determinant() const override {return mSecondMap.determinant();} // no implementation
2326 
2329  double determinant(const Vec3d& loc) const override
2330  {
2331  double s = mGamma * loc.z() + 1.0;
2332  double frustum_determinant = s * s * mDepthOnLzLxLx;
2333  return mSecondMap.determinant() * frustum_determinant;
2334  }
2335 
2337  Vec3d voxelSize() const override
2338  {
2339  const Vec3d loc( 0.5*(mBBox.min().x() + mBBox.max().x()),
2340  0.5*(mBBox.min().y() + mBBox.max().y()),
2341  mBBox.min().z());
2342 
2343  return voxelSize(loc);
2344 
2345  }
2346 
2351  Vec3d voxelSize(const Vec3d& loc) const override
2352  {
2353  Vec3d out, pos = applyMap(loc);
2354  out(0) = (applyMap(loc + Vec3d(1,0,0)) - pos).length();
2355  out(1) = (applyMap(loc + Vec3d(0,1,0)) - pos).length();
2356  out(2) = (applyMap(loc + Vec3d(0,0,1)) - pos).length();
2357  return out;
2358  }
2359 
2360  AffineMap::Ptr getAffineMap() const override { return mSecondMap.getAffineMap(); }
2361 
2363  void setTaper(double t) { mTaper = t; init();}
2365  double getTaper() const { return mTaper; }
2367  void setDepth(double d) { mDepth = d; init();}
2369  double getDepth() const { return mDepth; }
2370  // gamma a non-dimensional number: nearplane x-width / camera to near plane distance
2371  double getGamma() const { return mGamma; }
2372 
2374  const BBoxd& getBBox() const { return mBBox; }
2375 
2377  const AffineMap& secondMap() const { return mSecondMap; }
2380  bool isValid() const { return !mBBox.empty();}
2381 
2383  bool hasSimpleAffine() const { return mHasSimpleAffine; }
2384 
2386  void read(std::istream& is) override
2387  {
2388  // for backward compatibility with earlier version
2390  CoordBBox bb;
2391  bb.read(is);
2392  mBBox = BBoxd(bb.min().asVec3d(), bb.max().asVec3d());
2393  } else {
2394  mBBox.read(is);
2395  }
2396 
2397  is.read(reinterpret_cast<char*>(&mTaper), sizeof(double));
2398  is.read(reinterpret_cast<char*>(&mDepth), sizeof(double));
2399 
2400  // Read the second maps type.
2401  Name type = readString(is);
2402 
2403  // Check if the map has been registered.
2404  if(!MapRegistry::isRegistered(type)) {
2405  OPENVDB_THROW(KeyError, "Map " << type << " is not registered");
2406  }
2407 
2408  // Create the second map of the type and then read it in.
2409  MapBase::Ptr proxy = math::MapRegistry::createMap(type);
2410  proxy->read(is);
2411  mSecondMap = *(proxy->getAffineMap());
2412  init();
2413  }
2414 
2416  void write(std::ostream& os) const override
2417  {
2418  mBBox.write(os);
2419  os.write(reinterpret_cast<const char*>(&mTaper), sizeof(double));
2420  os.write(reinterpret_cast<const char*>(&mDepth), sizeof(double));
2421 
2422  writeString(os, mSecondMap.type());
2423  mSecondMap.write(os);
2424  }
2425 
2427  std::string str() const override
2428  {
2429  std::ostringstream buffer;
2430  buffer << " - taper: " << mTaper << std::endl;
2431  buffer << " - depth: " << mDepth << std::endl;
2432  buffer << " SecondMap: "<< mSecondMap.type() << std::endl;
2433  buffer << mSecondMap.str() << std::endl;
2434  return buffer.str();
2435  }
2436 
2439  MapBase::Ptr preRotate(double radians, Axis axis = X_AXIS) const override
2440  {
2441  return MapBase::Ptr(
2442  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preRotate(radians, axis)));
2443  }
2446  MapBase::Ptr preTranslate(const Vec3d& t) const override
2447  {
2448  return MapBase::Ptr(
2449  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preTranslate(t)));
2450  }
2453  MapBase::Ptr preScale(const Vec3d& s) const override
2454  {
2455  return MapBase::Ptr(
2456  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.preScale(s)));
2457  }
2460  MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
2461  {
2462  return MapBase::Ptr(new NonlinearFrustumMap(
2463  mBBox, mTaper, mDepth, mSecondMap.preShear(shear, axis0, axis1)));
2464  }
2465 
2468  MapBase::Ptr postRotate(double radians, Axis axis = X_AXIS) const override
2469  {
2470  return MapBase::Ptr(
2471  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postRotate(radians, axis)));
2472  }
2475  MapBase::Ptr postTranslate(const Vec3d& t) const override
2476  {
2477  return MapBase::Ptr(
2478  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postTranslate(t)));
2479  }
2482  MapBase::Ptr postScale(const Vec3d& s) const override
2483  {
2484  return MapBase::Ptr(
2485  new NonlinearFrustumMap(mBBox, mTaper, mDepth, mSecondMap.postScale(s)));
2486  }
2489  MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
2490  {
2491  return MapBase::Ptr(new NonlinearFrustumMap(
2492  mBBox, mTaper, mDepth, mSecondMap.postShear(shear, axis0, axis1)));
2493  }
2494 
2495 private:
2496  void init()
2497  {
2498  // set up as a frustum
2499  mLx = mBBox.extents().x();
2500  mLy = mBBox.extents().y();
2501  mLz = mBBox.extents().z();
2502 
2503  if (isApproxEqual(mLx,0.) || isApproxEqual(mLy,0.) || isApproxEqual(mLz,0.) ) {
2504  OPENVDB_THROW(ArithmeticError, "The index space bounding box"
2505  " must have at least two index points in each direction.");
2506  }
2507 
2508  mXo = 0.5* mLx;
2509  mYo = 0.5* mLy;
2510 
2511  // mDepth is non-dimensionalized on near
2512  mGamma = (1./mTaper - 1) / mDepth;
2513 
2514  mDepthOnLz = mDepth/mLz;
2515  mDepthOnLzLxLx = mDepthOnLz/(mLx * mLx);
2516 
2518  mHasSimpleAffine = true;
2519  Vec3d tmp = mSecondMap.voxelSize();
2520 
2522  if (!isApproxEqual(tmp(0), tmp(1))) { mHasSimpleAffine = false; return; }
2523  if (!isApproxEqual(tmp(0), tmp(2))) { mHasSimpleAffine = false; return; }
2524 
2525  Vec3d trans = mSecondMap.applyMap(Vec3d(0,0,0));
2527  Vec3d tmp1 = mSecondMap.applyMap(Vec3d(1,0,0)) - trans;
2528  Vec3d tmp2 = mSecondMap.applyMap(Vec3d(0,1,0)) - trans;
2529  Vec3d tmp3 = mSecondMap.applyMap(Vec3d(0,0,1)) - trans;
2530 
2532  if (!isApproxEqual(tmp1.dot(tmp2), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2533  if (!isApproxEqual(tmp2.dot(tmp3), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2534  if (!isApproxEqual(tmp3.dot(tmp1), 0., 1.e-7)) { mHasSimpleAffine = false; return; }
2535  }
2536 
2537  Vec3d applyFrustumMap(const Vec3d& in) const
2538  {
2539 
2540  // Move the center of the x-face of the bbox
2541  // to the origin in index space.
2542  Vec3d out(in);
2543  out = out - mBBox.min();
2544  out.x() -= mXo;
2545  out.y() -= mYo;
2546 
2547  // scale the z-direction on depth / K count
2548  out.z() *= mDepthOnLz;
2549 
2550  double scale = (mGamma * out.z() + 1.)/ mLx;
2551 
2552  // scale the x-y on the length I count and apply tapper
2553  out.x() *= scale ;
2554  out.y() *= scale ;
2555 
2556  return out;
2557  }
2558 
2559  Vec3d applyFrustumInverseMap(const Vec3d& in) const
2560  {
2561  // invert taper and resize: scale = 1/( (z+1)/2 (mt-1) + 1)
2562  Vec3d out(in);
2563  double invScale = mLx / (mGamma * out.z() + 1.);
2564  out.x() *= invScale;
2565  out.y() *= invScale;
2566 
2567  out.x() += mXo;
2568  out.y() += mYo;
2569 
2570  out.z() /= mDepthOnLz;
2571 
2572  // move back
2573  out = out + mBBox.min();
2574  return out;
2575  }
2576 
2577  // bounding box in index space used in Frustum transforms.
2578  BBoxd mBBox;
2579 
2580  // taper value used in constructing Frustums.
2581  double mTaper;
2582  double mDepth;
2583 
2584  // defines the second map
2585  AffineMap mSecondMap;
2586 
2587  // these are derived from the above.
2588  double mLx, mLy, mLz;
2589  double mXo, mYo, mGamma, mDepthOnLz, mDepthOnLzLxLx;
2590 
2591  // true: if the mSecondMap is linear and has no shear, and has no non-uniform scale
2592  bool mHasSimpleAffine;
2593 }; // class NonlinearFrustumMap
2594 
2595 
2597 
2598 
2602 template<typename FirstMapType, typename SecondMapType>
2603 class CompoundMap
2604 {
2605 public:
2607 
2610 
2611 
2612  CompoundMap() { updateAffineMatrix(); }
2613 
2614  CompoundMap(const FirstMapType& f, const SecondMapType& s): mFirstMap(f), mSecondMap(s)
2615  {
2616  updateAffineMatrix();
2617  }
2618 
2619  CompoundMap(const MyType& other):
2620  mFirstMap(other.mFirstMap),
2621  mSecondMap(other.mSecondMap),
2622  mAffineMap(other.mAffineMap)
2623  {}
2624 
2625  Name type() const { return mapType(); }
2626  static Name mapType()
2627  {
2628  return (FirstMapType::mapType() + Name(":") + SecondMapType::mapType());
2629  }
2630 
2631  bool operator==(const MyType& other) const
2632  {
2633  if (mFirstMap != other.mFirstMap) return false;
2634  if (mSecondMap != other.mSecondMap) return false;
2635  if (mAffineMap != other.mAffineMap) return false;
2636  return true;
2637  }
2638 
2639  bool operator!=(const MyType& other) const { return !(*this == other); }
2640 
2641  MyType& operator=(const MyType& other)
2642  {
2643  mFirstMap = other.mFirstMap;
2644  mSecondMap = other.mSecondMap;
2645  mAffineMap = other.mAffineMap;
2646  return *this;
2647  }
2648 
2649  bool isIdentity() const
2650  {
2652  return mAffineMap.isIdentity();
2653  } else {
2654  return mFirstMap.isIdentity()&&mSecondMap.isIdentity();
2655  }
2656  }
2657 
2658  bool isDiagonal() const {
2660  return mAffineMap.isDiagonal();
2661  } else {
2662  return mFirstMap.isDiagonal()&&mSecondMap.isDiagonal();
2663  }
2664  }
2665 
2667  {
2669  AffineMap::Ptr affine(new AffineMap(mAffineMap));
2670  return affine;
2671  } else {
2673  "Constant affine matrix representation not possible for this nonlinear map");
2674  }
2675  }
2676 
2677  // direct decompotion
2678  const FirstMapType& firstMap() const { return mFirstMap; }
2679  const SecondMapType& secondMap() const {return mSecondMap; }
2680 
2681  void setFirstMap(const FirstMapType& first) { mFirstMap = first; updateAffineMatrix(); }
2682  void setSecondMap(const SecondMapType& second) { mSecondMap = second; updateAffineMatrix(); }
2683 
2684  void read(std::istream& is)
2685  {
2686  mAffineMap.read(is);
2687  mFirstMap.read(is);
2688  mSecondMap.read(is);
2689  }
2690  void write(std::ostream& os) const
2691  {
2692  mAffineMap.write(os);
2693  mFirstMap.write(os);
2694  mSecondMap.write(os);
2695  }
2696 
2697 private:
2698  void updateAffineMatrix()
2699  {
2701  // both maps need to be linear, these methods are only defined for linear maps
2702  AffineMap::Ptr first = mFirstMap.getAffineMap();
2703  AffineMap::Ptr second= mSecondMap.getAffineMap();
2704  mAffineMap = AffineMap(*first, *second);
2705  }
2706  }
2707 
2708  FirstMapType mFirstMap;
2709  SecondMapType mSecondMap;
2710  // used for acceleration
2711  AffineMap mAffineMap;
2712 }; // class CompoundMap
2713 
2714 } // namespace math
2715 } // namespace OPENVDB_VERSION_NAME
2716 } // namespace openvdb
2717 
2718 #endif // OPENVDB_MATH_MAPS_HAS_BEEN_INCLUDED
2719 
2720 // Copyright (c) 2012-2017 DreamWorks Animation LLC
2721 // All rights reserved. This software is distributed under the
2722 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
static void registerMap()
Definition: Maps.h:1521
static MapBase::Ptr create()
Return a MapBase::Ptr to a new NonlinearFrustumMap.
Definition: Maps.h:2030
ScaleTranslateMap(const ScaleTranslateMap &other)
Definition: Maps.h:1226
UnitaryMap(const UnitaryMap &first, const UnitaryMap &second)
Definition: Maps.h:1699
std::string str() const override
string serialization, useful for debuging
Definition: Maps.h:1381
bool isAffine(const Mat4< T > &m)
Definition: Mat4.h:1363
Vec3d voxelSize() const override
Return the size of a voxel at the center of the near plane.
Definition: Maps.h:2337
static Name mapType()
Definition: Maps.h:737
MapBase::Ptr preTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1419
Vec3d applyInverseJacobian(const Vec3d &in) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:1302
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1014
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:451
const Vec3d & getInvScale() const
Return 1/(scale)
Definition: Maps.h:823
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:370
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
CompoundMap< CompoundMap< UnitaryMap, ScaleMap >, UnitaryMap > SpectralDecomposedMap
Definition: Maps.h:69
MapBase::Ptr postTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of appending the given translation.
Definition: Maps.h:1865
void read(std::istream &is) override
read serialization
Definition: Maps.h:1089
Definition: Maps.h:103
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:1049
void setCol(int j, const Vec3< T > &v)
Set jth column to vector v.
Definition: Mat3.h:192
std::string str() const override
string serialization, useful for debuging
Definition: Maps.h:1093
static Name mapType()
Definition: Maps.h:1030
AffineMap(const AffineMap &other)
Definition: Maps.h:359
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UniformScaleMap.
Definition: Maps.h:938
const Vec3d & getInvScaleSqr() const
Return the square of the scale. Used to optimize some finite difference calculations.
Definition: Maps.h:1354
MapBase::Ptr postTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a UniformScaleTranslateMap that is the result of postfixing translation on t...
Definition: Maps.h:1549
Vec3d applyJT(const Vec3d &in) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1061
AffineMap::Ptr getAffineMap() const override
Return a AffineMap equivalent to this map.
Definition: Maps.h:872
bool hasUniformScale() const override
Return true if the scale values have the same magnitude (eg. -1, 1, -1 would be a rotation)...
Definition: Maps.h:1266
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given shear.
Definition: Maps.h:1848
void read(std::istream &is) override
read serialization
Definition: Maps.h:834
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:1931
MapBase::Ptr inverseMap() const override
Not implemented, since there is currently no map type that can represent the inverse of a frustum...
Definition: Maps.h:2037
std::string str() const override
string serialization, useful for debugging
Definition: Maps.h:561
bool operator==(const TranslationMap &other) const
Definition: Maps.h:1102
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const override
Apply the Jacobian of this map to a vector. For a linear map this is equivalent to applying the map e...
Definition: Maps.h:1751
double determinant() const override
Return the determinant of the Jacobian.
Definition: Maps.h:1789
Vec3d applyInverseMap(const Vec3d &in) const override
Return the pre-image of in under the map.
Definition: Maps.h:442
bool isLinear() const override
Return true (a TranslationMap is always linear).
Definition: Maps.h:1033
MapBase::Ptr preTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given translation to the line...
Definition: Maps.h:2446
Vec3d applyIJT(const Vec3d &in) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:792
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:472
Vec3d applyIJT(const Vec3d &in) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:474
bool operator!=(const TranslationMap &other) const
Definition: Maps.h:1108
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:1016
AffineMap::Ptr getAffineMap() const override
Definition: Maps.h:2360
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Vec3d applyInverseMap(const Vec3d &in) const override
Return the pre-image of in under the map.
Definition: Maps.h:2114
Name type() const override
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:1258
Vec3d applyInverseJacobian(const Vec3d &in) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:2146
void read(std::istream &is) override
read serialization
Definition: Maps.h:2386
static Name mapType()
Definition: Maps.h:397
OPENVDB_API SharedPtr< FullyDecomposedMap > createFullyDecomposedMap(const Mat4d &m)
General decomposition of a Matrix into a Unitary (e.g. rotation) following a Symmetric (e...
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:324
UniformScaleTranslateMap(const UniformScaleMap &scale, const TranslationMap &translate)
Definition: Maps.h:1498
bool hasUniformScale() const override
Return false ( test if this is unitary with translation )
Definition: Maps.h:403
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation to the ...
Definition: Maps.h:891
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:1043
void setRow(int i, const Vec3< T > &v)
Set ith row to vector v.
Definition: Mat3.h:174
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given shear to the linear par...
Definition: Maps.h:2460
static void registerMap()
Definition: Maps.h:2044
ScaleMap(const ScaleMap &other)
Definition: Maps.h:706
Vec3d applyJT(const Vec3d &in, const Vec3d &) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1768
Vec3d applyJacobian(const Vec3d &in) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:1295
Vec3d applyIJT(const Vec3d &d1_is, const Vec3d &ijk) const override
Definition: Maps.h:2214
std::string str() const override
string serialization, useful for debuging
Definition: Maps.h:2427
UniformScaleMap(double scale)
Definition: Maps.h:933
Vec3d asVec3d() const
Definition: Coord.h:167
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:2081
double getDepth() const
Return the unscaled frustm depth.
Definition: Maps.h:2369
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:1736
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:1757
Vec3d applyJT(const Vec3d &in) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1308
SharedPtr< AffineMap > Ptr
Definition: Maps.h:327
bool isDiagonal() const
Return true if the underylying matrix is diagonal.
Definition: Maps.h:497
T length() const
Length of the vector.
Definition: Vec3.h:224
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:266
T & z()
Definition: Vec3.h:111
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
bool operator!=(const UniformScaleMap &other) const
Definition: Maps.h:962
Vec3d voxelSize(const Vec3d &) const override
Return the absolute values of the scale values, ignores argument.
Definition: Maps.h:1346
void read(std::istream &is) override
read serialization
Definition: Maps.h:1361
NonlinearFrustumMap()
Definition: Maps.h:1908
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:683
static void registerMap()
Definition: Maps.h:729
Mat3d applyIJC(const Mat3d &in) const override
Return the Jacobian Curvature for the linear second map.
Definition: Maps.h:2250
void read(std::istream &is) override
read serialization
Definition: Maps.h:1800
void write(std::ostream &os) const override
write serialization
Definition: Maps.h:1091
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:502
void accumPostShear(Axis axis0, Axis axis1, double shear)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:548
bool operator==(const UniformScaleMap &other) const
Definition: Maps.h:961
bool hasUniformScale() const override
Return false (by convention true)
Definition: Maps.h:1734
Mat3d applyIJC(const Mat3d &mat) const override
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1070
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &isloc) const override
Return the Inverse Jacobian defined at isloc of the map applied to in.
Definition: Maps.h:2150
Vec3d applyInverseJacobian(const Vec3d &in) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:780
static Name mapType()
Return UnitaryMap.
Definition: Maps.h:1728
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:855
MapBase::Ptr postTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropriate operation...
Definition: Maps.h:1155
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:682
const Vec3d & getInvScale() const
Return 1/(scale)
Definition: Maps.h:1358
static MapBase::Ptr create()
Return a MapBase::Ptr to a new AffineMap.
Definition: Maps.h:381
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:1299
const Mat4d & getConstMat4() const
Definition: Maps.h:643
void setTaper(double t)
set the taper value, the ratio of nearplane width / far plane width
Definition: Maps.h:2363
static bool isRegistered()
Definition: Maps.h:1020
static bool isRegistered()
Definition: Maps.h:727
UnitaryMap(const Mat3d &m)
Definition: Maps.h:1656
bool operator!=(const UnitaryMap &other) const
Definition: Maps.h:1745
Vec3d applyInverseJacobian(const Vec3d &in) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:456
void accumPostTranslation(const Vec3d &v)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:543
void accumPostScale(const Vec3d &v)
Modify the existing affine map by post-applying the given operation.
Definition: Maps.h:538
bool operator!=(const AffineMap &other) const
Definition: Maps.h:425
MapBase::Ptr preRotate(double radians, Axis axis) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given rotation.
Definition: Maps.h:1824
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of appending the given shear.
Definition: Maps.h:1881
Vec3d applyIJT(const Vec3d &in) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1314
static bool isRegistered()
Definition: Maps.h:1716
static void registerMap()
Definition: Maps.h:1022
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:633
std::string str() const override
string serialization, useful for debuging
Definition: Maps.h:852
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const override
Definition: Maps.h:1782
bool operator!=(const ScaleMap &other) const
Definition: Maps.h:869
Vec3< typename MatType::value_type > getScale(const MatType &mat)
Return a Vec3 representing the lengths of the passed matrix&#39;s upper 3x3&#39;s rows.
Definition: Mat.h:628
const BBoxd & getBBox() const
Return the bounding box that defines the frustum in pre-image space.
Definition: Maps.h:2374
void write(std::ostream &os) const override
write serialization
Definition: Maps.h:1371
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:1100
AffineMap::Ptr getAffineMap() const override
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1403
bool isScale() const
Return true if the map is equivalent to a ScaleMap.
Definition: Maps.h:499
Vec3d applyJacobian(const Vec3d &in, const Vec3d &isloc) const override
Return the Jacobian defined at isloc applied to in.
Definition: Maps.h:2121
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:1509
static bool isRegistered()
Definition: Maps.h:2042
Name type() const override
Return NonlinearFrustumMap.
Definition: Maps.h:2051
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:723
const Vec3d & getInvTwiceScale() const
Return 1/(2 scale). Used to optimize some finite difference calculations.
Definition: Maps.h:1356
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:445
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:610
static Name mapType()
Definition: Maps.h:1528
void write(std::ostream &os) const override
write serialization
Definition: Maps.h:1806
Mat3d applyIJC(const Mat3d &mat, const Vec3d &, const Vec3d &) const override
Definition: Maps.h:1071
void write(std::ostream &os) const override
write serialization
Definition: Maps.h:2416
const FirstMapType & firstMap() const
Definition: Maps.h:2678
Vec3d applyInverseJacobian(const Vec3d &in) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:1762
double getGamma() const
Definition: Maps.h:2371
const Vec3d & getInvScaleSqr() const
Return the square of the scale. Used to optimize some finite difference calculations.
Definition: Maps.h:819
bool isLinear() const override
Return true (a ScaleTranslateMap is always linear).
Definition: Maps.h:1262
std::string str() const override
string serialization, useful for debuging
Definition: Maps.h:1811
SharedPtr< MyType > Ptr
Definition: Maps.h:2608
bool operator!=(const UniformScaleTranslateMap &other) const
Definition: Maps.h:1536
bool hasUniformScale() const override
Return false (by convention true)
Definition: Maps.h:1036
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UniformScaleTranslateMap.
Definition: Maps.h:1505
double determinant(const Vec3d &) const override
Return the product of the scale values, ignores argument.
Definition: Maps.h:1338
Vec3d voxelSize() const override
Return .
Definition: Maps.h:1081
static bool isRegistered()
Definition: Maps.h:387
UniformScaleMap()
Definition: Maps.h:932
bool isIdentity() const
Return true if the map is equivalent to an identity.
Definition: Maps.h:2062
const Vec3d & getTranslation() const
Return the translation vector.
Definition: Maps.h:1086
math::BBox< Vec3d > BBoxd
Definition: Types.h:87
Vec3< T > row(int i) const
Get ith row, e.g. Vec3d v = m.row(1);.
Definition: Mat3.h:185
bool isScaleTranslate() const
Return true if the map is equivalent to a ScaleTranslateMap.
Definition: Maps.h:501
bool isType() const
Return true if this map is of concrete type MapT (e.g., AffineMap).
Definition: Maps.h:174
Mat3d applyIJC(const Mat3d &in) const override
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1322
const Coord & min() const
Definition: Coord.h:339
static void registerMap()
Definition: Maps.h:389
const Vec3d & getScale() const
Returns the scale values.
Definition: Maps.h:1349
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:1920
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:1243
A specialized linear transform that performs a unitary maping i.e. rotation and or reflection...
Definition: Maps.h:1631
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:942
MyType & operator=(const MyType &other)
Definition: Maps.h:2641
void write(std::ostream &os) const override
write serialization
Definition: Maps.h:843
Vec3d applyIJT(const Vec3d &in) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1779
Vec3d applyJT(const Vec3d &in) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:464
void write(std::ostream &os) const
Definition: Maps.h:2690
const AffineMap & secondMap() const
Return MapBase::Ptr& to the second map.
Definition: Maps.h:2377
ScaleMap()
Definition: Maps.h:688
T * asPointer()
Definition: Vec3.h:118
UniformScaleMap(const UniformScaleMap &other)
Definition: Maps.h:934
Vec3d applyJT(const Vec3d &in) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1770
void accumPreScale(const Vec3d &v)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:513
Mat4d getMat4() const
Return the matrix representation of this AffineMap.
Definition: Maps.h:642
AffineMap::Ptr inverse() const
Return AffineMap::Ptr to the inverse of this map.
Definition: Maps.h:579
Vec3d voxelSize(const Vec3d &loc) const override
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:2351
A specialized linear transform that performs a translation.
Definition: Maps.h:998
Creates the composition of two maps, each of which could be a composition. In the case that each comp...
Definition: Maps.h:66
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:1530
ScaleTranslateMap(const Vec3d &scale, const Vec3d &translate)
Definition: Maps.h:1198
OPENVDB_API Mat4d approxInverse(const Mat4d &mat)
Returns the left pseudoInverse of the input matrix when the 3x3 part is symmetric otherwise it zeros ...
void read(std::istream &is) override
read serialization
Definition: Maps.h:557
AffineMap(const Mat3d &m)
Definition: Maps.h:342
void accumPreShear(Axis axis0, Axis axis1, double shear)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:523
Vec3d applyMap(const Vec3d &in) const override
Return the image of in under the map.
Definition: Maps.h:440
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:769
Vec3d applyMap(const Vec3d &in) const override
Return the image of under the map.
Definition: Maps.h:1276
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:1181
MapBase::Ptr postScale(const Vec3d &s) const override
Return a MapBase::Ptr to a new map that is the result of appending the given scale to the linear part...
Definition: Maps.h:2482
#define OPENVDB_VERSION_NAME
Definition: version.h:43
AffineMap(const Mat4d &m)
Definition: Maps.h:350
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1777
MapBase::Ptr preTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation...
Definition: Maps.h:1130
Vec3< double > Vec3d
Definition: Vec3.h:708
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of appending the given shear to the linear part...
Definition: Maps.h:2489
ScaleTranslateMap()
Definition: Maps.h:1187
static MapBase::Ptr create()
Return a MapBase::Ptr to a new ScaleTranslateMap.
Definition: Maps.h:1239
MapBase::Ptr postRotate(double radians, Axis axis) const override
Return a MapBase::Ptr to a new map that is the result of appending the given rotation.
Definition: Maps.h:1857
void setDepth(double d)
set the frustum depth: distance between near and far plane = frustm depth * frustm x-width ...
Definition: Maps.h:2367
T det() const
Determinant of matrix.
Definition: Mat3.h:533
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const override
Return the transpose of the inverse Jacobian (Identity for TranslationMap) of the map applied to in...
Definition: Maps.h:1065
Name readString(std::istream &is)
Definition: Name.h:47
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:940
bool operator==(const UnitaryMap &other) const
Definition: Maps.h:1738
MapBase::Ptr postRotate(double radians, Axis axis=X_AXIS) const override
Return a MapBase::Ptr to a new map that is the result of appending the given rotation to the linear p...
Definition: Maps.h:2468
bool operator==(const AffineMap &other) const
Definition: Maps.h:417
void setFirstMap(const FirstMapType &first)
Definition: Maps.h:2681
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:1390
bool hasUniformScale() const override
Return false (by convention false)
Definition: Maps.h:2059
A specialized Affine transform that uniformaly scales along the principal axis and then translates th...
Definition: Maps.h:1489
const SecondMapType & secondMap() const
Definition: Maps.h:2679
Mat3< T > getMat3() const
Definition: Mat4.h:351
double determinant(const Vec3d &) const override
Return the determinant of the Jacobian, ignores argument.
Definition: Maps.h:1787
Name type() const override
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:736
Vec3d applyJacobian(const Vec3d &in) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:1753
bool operator==(const UniformScaleTranslateMap &other) const
Definition: Maps.h:1532
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:1969
static Name mapType()
Definition: Maps.h:957
MapBase()
Definition: Maps.h:271
Vec3d applyInverseJacobian(const Vec3d &in, const Vec3d &) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:775
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:215
AffineMap()
Definition: Maps.h:330
UniformScaleTranslateMap()
Definition: Maps.h:1495
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:376
CompoundMap()
Definition: Maps.h:2612
UnitaryMap(const Vec3d &axis, double radians)
Definition: Maps.h:1642
Vec3< T > col(int j) const
Get jth column, e.g. Vec3d v = m.col(0);.
Definition: Mat3.h:201
Definition: Exceptions.h:39
Vec3d applyInverseMap(const Vec3d &in) const override
Return the pre-image of in under the map.
Definition: Maps.h:1749
Vec3d applyInverseMap(const Vec3d &in) const override
Return the pre-image of in under the map.
Definition: Maps.h:1041
bool hasSimpleAffine() const
Return true if the second map is a uniform scale, Rotation and translation.
Definition: Maps.h:2383
double determinant(const Vec3d &loc) const override
Definition: Maps.h:2329
bool hasUniformScale() const override
Return true if the values have the same magitude (eg. -1, 1, -1 would be a rotation).
Definition: Maps.h:743
MapBase::Ptr preTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given translation.
Definition: Maps.h:1832
static MapBase::Ptr create()
Return a MapBase::Ptr to a new ScaleMap.
Definition: Maps.h:719
OPENVDB_API SharedPtr< PolarDecomposedMap > createPolarDecomposedMap(const Mat3d &m)
Decomposes a general linear into translation following polar decomposition.
SharedPtr< UnitaryMap > Ptr
Definition: Maps.h:1634
UnitaryMap(const Mat4d &m)
Definition: Maps.h:1668
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:109
Vec3d applyJacobian(const Vec3d &in) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:447
Name type() const override
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:1029
bool operator==(const MyType &other) const
Definition: Maps.h:2631
T & y()
Definition: Vec3.h:110
bool operator==(const ScaleTranslateMap &other) const
Definition: Maps.h:1392
Mat3d applyIJC(const Mat3d &d2_is, const Vec3d &d1_is, const Vec3d &ijk) const override
Definition: Maps.h:2255
TranslationMap(const TranslationMap &other)
Definition: Maps.h:1007
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1241
Int32 ValueType
Definition: Coord.h:56
const Vec3d & getScale() const
Return the scale values that define the map.
Definition: Maps.h:816
Mat3 transpose() const
returns transpose of this
Definition: Mat3.h:508
bool isLinear() const override
Return true (a ScaleMap is always linear).
Definition: Maps.h:740
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:383
static Name mapType()
Definition: Maps.h:1259
MapBase::Ptr preRotate(double radians, Axis axis=X_AXIS) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given rotation to the linear ...
Definition: Maps.h:2439
Vec4< T0 > transform(const Vec4< T0 > &v) const
Transform a Vec4 by post-multiplication.
Definition: Mat4.h:1052
double determinant() const override
Return the product of the scale values.
Definition: Maps.h:1340
ScaleMap(const Vec3d &scale)
Definition: Maps.h:692
Vec3d applyJT(const Vec3d &in, const Vec3d &) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:784
UnitaryMap()
default constructor makes an Idenity.
Definition: Maps.h:1638
MapBase::Ptr postTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1447
const Coord & max() const
Definition: Coord.h:340
UnitaryMap(const UnitaryMap &other)
Definition: Maps.h:1693
CompoundMap(const MyType &other)
Definition: Maps.h:2619
AffineMap::Ptr getAffineMap() const
Definition: Maps.h:2666
MapBase::Ptr preTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:591
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:2032
Definition: Exceptions.h:82
SharedPtr< const MyType > ConstPtr
Definition: Maps.h:2609
Vec3d voxelSize(const Vec3d &) const override
Return the lengths of the images of the segments , , .
Definition: Maps.h:830
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:860
void write(std::ostream &os) const override
write serialization
Definition: Maps.h:559
Mat3d applyIJC(const Mat3d &m) const override
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:476
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:168
bool isUnitary(const MatType &m)
Determine if a matrix is unitary (i.e., rotation or reflection).
Definition: Mat.h:884
AffineMap::Ptr getAffineMap() const override
Return AffineMap::Ptr to a deep copy of the current AffineMap.
Definition: Maps.h:576
Vec3d applyMap(const Vec3d &in) const override
Return the image of in under the map.
Definition: Maps.h:1039
static Name mapType()
Return NonlinearFrustumMap.
Definition: Maps.h:2053
static void registerMap()
Definition: Maps.h:1251
ScaleTranslateMap(const ScaleMap &scale, const TranslationMap &translate)
Definition: Maps.h:1213
MapBase::Ptr preTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a UniformScaleTranslateMap that is the result of prepending translation on t...
Definition: Maps.h:1540
TranslationMap()
Definition: Maps.h:1005
Vec3d applyMap(const Vec3d &in) const override
Return the image of in under the map.
Definition: Maps.h:753
Name type() const override
Return UnitaryMap.
Definition: Maps.h:1726
double determinant(const Vec3d &) const override
Return the product of the scale values, ignores argument.
Definition: Maps.h:809
static void registerMap()
Definition: Maps.h:1718
Mat4 inverse(T tolerance=0) const
Definition: Mat4.h:539
Mat3d applyIJC(const Mat3d &in) const override
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:1781
MapBase::Ptr preScale(const Vec3d &s) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:597
MapBase::Ptr postScale(const Vec3d &s) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:627
void setSecondMap(const SecondMapType &second)
Definition: Maps.h:2682
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
std::string Name
Definition: Name.h:44
void writeString(std::ostream &os, const Name &name)
Definition: Name.h:58
const Vec3d & getInvTwiceScale() const
Return 1/(2 scale). Used to optimize some finite difference calculations.
Definition: Maps.h:821
Vec3d applyJacobian(const Vec3d &in) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:771
static bool isRegistered()
Definition: Maps.h:948
double getTaper() const
Return the taper value.
Definition: Maps.h:2365
Vec3d voxelSize(const Vec3d &) const override
Return .
Definition: Maps.h:1083
Vec3d applyIJT(const Vec3d &in) const override
Return the transpose of the inverse Jacobian of the linear second map applied to in.
Definition: Maps.h:2204
bool isLinear() const override
Return true (an AffineMap is always linear).
Definition: Maps.h:400
Abstract base class for maps.
Definition: Maps.h:158
This map is composed of three steps. First it will take a box of size (Lx X Ly X Lz) defined by a mem...
Definition: Maps.h:1902
SharedPtr< const MapBase > ConstPtr
Definition: Maps.h:162
MapBase::Ptr copy() const override
Returns a MapBase::Ptr to a deep copy of *this.
Definition: Maps.h:1709
Vec3d applyMap(const Vec3d &in) const override
Return the image of in under the map.
Definition: Maps.h:1747
Vec3d applyJT(const Vec3d &in, const Vec3d &) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1059
Definition: Exceptions.h:88
Vec3d voxelSize() const override
Returns the lengths of the images of the segments , , .
Definition: Maps.h:1796
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropriate operation...
Definition: Maps.h:1137
Map traits.
Definition: Maps.h:79
double determinant() const override
Return the determinant of the Jacobian of linear second map.
Definition: Maps.h:2325
Vec3d applyJacobian(const Vec3d &in) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:1045
bool operator==(const NonlinearFrustumMap &other) const
Definition: Maps.h:2083
Vec3d applyJT(const Vec3d &in, const Vec3d &) const override
Definition: Maps.h:462
OPENVDB_API SharedPtr< SymmetricMap > createSymmetricMap(const Mat3d &m)
Utility methods.
bool operator!=(const MyType &other) const
Definition: Maps.h:2639
MapBase::Ptr postScale(const Vec3d &v) const override
Return a MapBase::Ptr to a new map that is the result of appending the given scale.
Definition: Maps.h:1873
std::shared_ptr< T > SharedPtr
Definition: Types.h:130
Vec3d applyMap(const Vec3d &in) const override
Return the image of in under the map.
Definition: Maps.h:2108
void setToRotation(Axis axis, T angle)
Sets the matrix to a rotation about the given axis.
Definition: Mat4.h:837
MapBase::Ptr preScale(const Vec3d &s) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given scale to the linear par...
Definition: Maps.h:2453
bool isIdentity() const
Return true if the underlying matrix is approximately an identity.
Definition: Maps.h:495
UnitaryMap(Axis axis, double radians)
Definition: Maps.h:1649
MapBase::Ptr preScale(const Vec3d &v) const override
Return a MapBase::Ptr to a new map that is the result of prepending the given scale.
Definition: Maps.h:1840
Mat3 inverse(T tolerance=0) const
Definition: Mat3.h:519
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:785
bool isDiagonal() const
Definition: Maps.h:2658
void setToRotation(const Quat< T > &q)
Set this matrix to the rotation matrix specified by the quaternion.
Definition: Mat3.h:307
const Mat3d & getConstJacobianInv() const
Definition: Maps.h:644
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:415
Vec3d applyJT(const Vec3d &in) const override
Return the Jacobian Transpose of the second map applied to in.
Definition: Maps.h:2199
static MapBase::Ptr create()
Return a MapBase::Ptr to a new TranslationMap.
Definition: Maps.h:1012
Mat3d applyIJC(const Mat3d &in) const override
Return the Jacobian Curvature: zero for a linear map.
Definition: Maps.h:794
Axis
Definition: Math.h:856
Vec3d applyInverseMap(const Vec3d &in) const override
Return the pre-image of under the map.
Definition: Maps.h:1284
Name type() const override
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:396
Vec3d applyJacobian(const Vec3d &in, const Vec3d &) const override
Return the Jacobian of the map applied to in.
Definition: Maps.h:1293
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:385
MapBase::Ptr postTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of appending the given translation to the linea...
Definition: Maps.h:2475
TranslationMap(const Vec3d &t)
Definition: Maps.h:1006
bool isIdentity() const
Definition: Maps.h:2649
bool hasTranslation(const Mat4< T > &m)
Definition: Mat4.h:1368
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:1430
CompoundMap(const FirstMapType &f, const SecondMapType &s)
Definition: Maps.h:2614
A specialized Affine transform that scales along the principal axis the scaling is uniform in the thr...
Definition: Maps.h:926
static const Mat4< double > & identity()
Predefined constant for identity matrix.
Definition: Mat4.h:152
Vec3d applyJacobian(const Vec3d &in) const override
Return the Jacobian of the linear second map applied to in.
Definition: Maps.h:2119
Threadsafe singleton object for accessing the map type-name dictionary. Associates a map type-name wi...
Definition: Maps.h:286
Name type() const override
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:1527
AffineMap & operator=(const AffineMap &other)
Definition: Maps.h:427
Vec3d applyJT(const Vec3d &in) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:786
static void registerMap()
Definition: Maps.h:949
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
bool isDiagonal(const MatType &mat)
Determine if a matrix is diagonal.
Definition: Mat.h:897
SharedPtr< FullyDecomposedMap > createDecomposedMap()
on-demand decomposition of the affine map
Definition: Maps.h:570
Name type() const
Definition: Maps.h:2625
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const override
Definition: Maps.h:1333
MapBase::Ptr preShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation...
Definition: Maps.h:603
bool isValid() const
Definition: Maps.h:2380
Definition: Exceptions.h:86
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:790
OPENVDB_API SharedPtr< MapBase > simplify(SharedPtr< AffineMap > affine)
reduces an AffineMap to a ScaleMap or a ScaleTranslateMap when it can
Vec3d applyIJT(const Vec3d &in) const override
Return the transpose of the inverse Jacobian (Identity for TranslationMap) of the map applied to in...
Definition: Maps.h:1068
bool isInvertible(const MatType &m)
Determine if a matrix is invertible.
Definition: Mat.h:864
double determinant(const Vec3d &) const override
Return the determinant of the Jacobian, ignores argument.
Definition: Maps.h:483
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:1507
static bool isEqualBase(const MapT &self, const MapBase &other)
Definition: Maps.h:274
AffineMap::Ptr getAffineMap() const override
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1818
Vec3d applyJT(const Vec3d &in, const Vec3d &isloc) const override
Return the Jacobian Transpose of the map applied to vector in at indexloc.
Definition: Maps.h:2177
double determinant() const override
Return the determinant of the Jacobian.
Definition: Maps.h:485
bool operator!=(const ScaleTranslateMap &other) const
Definition: Maps.h:1400
AffineMap::Ptr getAffineMap() const override
Return AffineMap::Ptr to an AffineMap equivalent to *this.
Definition: Maps.h:1111
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const override
Definition: Maps.h:805
bool isLinear() const override
Return true (a UnitaryMap is always linear).
Definition: Maps.h:1731
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of prepending the appropraite operation to the ...
Definition: Maps.h:911
void accumPreTranslation(const Vec3d &v)
Modify the existing affine map by pre-applying the given operation.
Definition: Maps.h:518
static MapBase::Ptr create()
Return a MapBase::Ptr to a new UnitaryMap.
Definition: Maps.h:1707
AffineMap(const AffineMap &first, const AffineMap &second)
constructor that merges the matrixes for two affine maps
Definition: Maps.h:372
Vec3d voxelSize(const Vec3d &) const override
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:491
static bool isRegistered()
Definition: Maps.h:1516
static Name mapType()
Definition: Maps.h:2626
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: Coord.h:479
Vec3d applyJT(const Vec3d &in, const Vec3d &) const override
Return the Jacobian Transpose of the map applied to in.
Definition: Maps.h:1306
Vec3d applyIJT(const Vec3d &in, const Vec3d &) const override
Return the transpose of the inverse Jacobian of the map applied to in.
Definition: Maps.h:1312
void setTranslation(const Vec3< T > &t)
Definition: Mat4.h:368
Vec3d voxelSize() const override
Return the absolute values of the scale values.
Definition: Maps.h:1344
void read(std::istream &is)
Definition: Maps.h:2684
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropriate operation...
Definition: Maps.h:1162
Vec3d voxelSize(const Vec3d &) const override
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:1797
void setMat3(const Mat3< T > &m)
Set upper left to a Mat3.
Definition: Mat4.h:344
double determinant(const Vec3d &) const override
Return 1.
Definition: Maps.h:1076
MapBase::Ptr postTranslate(const Vec3d &t) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:621
std::map< Name, MapBase::MapFactory > MapDictionary
Definition: Maps.h:289
Vec3d applyInverseJacobian(const Vec3d &in) const override
Return the Inverse Jacobian of the map applied to in (i.e. inverse map with out translation) ...
Definition: Maps.h:1054
UniformScaleTranslateMap(const UniformScaleTranslateMap &other)
Definition: Maps.h:1501
MapBase::Ptr inverseMap() const override
Return a new map representing the inverse of this map.
Definition: Maps.h:1711
bool operator!=(const NonlinearFrustumMap &other) const
Definition: Maps.h:2105
bool isLinear() const override
Return false (a NonlinearFrustumMap is never linear).
Definition: Maps.h:2056
UniformScaleTranslateMap(double scale, const Vec3d &translate)
Definition: Maps.h:1496
bool isEqual(const MapBase &other) const override
Return true if this map is equal to the given map.
Definition: Maps.h:959
Vec3d applyInverseMap(const Vec3d &in) const override
Return the pre-image of in under the map.
Definition: Maps.h:761
Mat3d applyIJC(const Mat3d &in, const Vec3d &, const Vec3d &) const override
Definition: Maps.h:479
double determinant() const override
Return 1.
Definition: Maps.h:1078
bool operator==(const ScaleMap &other) const
Definition: Maps.h:862
MapBase::Ptr copy() const override
Return a MapBase::Ptr to a deep copy of this map.
Definition: Maps.h:721
NonlinearFrustumMap(const NonlinearFrustumMap &other)
Definition: Maps.h:1943
SharedPtr< MapBase > Ptr
Definition: Maps.h:161
const Vec3d & getTranslation() const
Returns the translation.
Definition: Maps.h:1351
Name type() const override
Return the name of this map&#39;s concrete type (e.g., "AffineMap").
Definition: Maps.h:956
Tolerance for floating-point comparison.
Definition: Math.h:125
static bool isRegistered()
Definition: Maps.h:1249
Definition: Math.h:857
double determinant() const override
Return the product of the scale values.
Definition: Maps.h:811
MapBase::Ptr postShear(double shear, Axis axis0, Axis axis1) const override
Return a MapBase::Ptr to a new map that is the result of postfixing the appropraite operation...
Definition: Maps.h:1454