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