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