HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Transform.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 #ifndef OPENVDB_MATH_TRANSFORM_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_TRANSFORM_HAS_BEEN_INCLUDED
33 
34 #include "Maps.h"
35 #include <openvdb/Types.h>
36 #include <iosfwd>
37 
38 namespace openvdb {
40 namespace OPENVDB_VERSION_NAME {
41 namespace math {
42 
43 // Forward declaration
44 class Transform;
45 
46 
47 // Utility methods
48 
49 /// @brief Calculate an axis-aligned bounding box in index space from an
50 /// axis-aligned bounding box in world space.
51 /// @see Transform::worldToIndex(const BBoxd&) const
52 OPENVDB_API void
53 calculateBounds(const Transform& t, const Vec3d& minWS, const Vec3d& maxWS,
54  Vec3d& minIS, Vec3d& maxIS);
55 
56 /// @todo Calculate an axis-aligned bounding box in index space from a
57 /// bounding sphere in world space.
58 //void calculateBounds(const Transform& t, const Vec3d& center, const Real radius,
59 // Vec3d& minIS, Vec3d& maxIS);
60 
61 
62 ////////////////////////////////////////
63 
64 
65 /// @class Transform
67 {
68 public:
71 
72  Transform(): mMap(MapBase::Ptr(new ScaleMap())) {}
73  Transform(const MapBase::Ptr&);
74  Transform(const Transform&);
76 
77  Ptr copy() const { return Ptr(new Transform(mMap->copy())); }
78 
79  //@{
80  /// @brief Create and return a shared pointer to a new transform.
81  static Transform::Ptr createLinearTransform(double voxelSize = 1.0);
82  static Transform::Ptr createLinearTransform(const Mat4R&);
83  static Transform::Ptr createFrustumTransform(const BBoxd&, double taper,
84  double depth, double voxelSize = 1.0);
85  //@}
86 
87  /// Return @c true if the transformation map is exclusively linear/affine.
88  bool isLinear() const { return mMap->isLinear(); }
89 
90  /// Return @c true if the transform is equivalent to an idenity.
91  bool isIdentity() const ;
92  /// Return the transformation map's type-name
93  Name mapType() const { return mMap->type(); }
94 
95 
96  //@{
97  /// @brief Update the linear (affine) map by prepending or
98  /// postfixing the appropriate operation. In the case of
99  /// a frustum, the pre-operations apply to the linear part
100  /// of the transform and not the entire transform, while the
101  /// post-operations are allways applied last.
102  void preRotate(double radians, const Axis axis = X_AXIS);
103  void preTranslate(const Vec3d&);
104  void preScale(const Vec3d&);
105  void preScale(double);
106  void preShear(double shear, Axis axis0, Axis axis1);
107  void preMult(const Mat4d&);
108  void preMult(const Mat3d&);
109 
110  void postRotate(double radians, const Axis axis = X_AXIS);
111  void postTranslate(const Vec3d&);
112  void postScale(const Vec3d&);
113  void postScale(double);
114  void postShear(double shear, Axis axis0, Axis axis1);
115  void postMult(const Mat4d&);
116  void postMult(const Mat3d&);
117  //@}
118 
119  /// Return the size of a voxel using the linear component of the map.
120  Vec3d voxelSize() const { return mMap->voxelSize(); }
121  /// @brief Return the size of a voxel at position (x, y, z).
122  /// @note Maps that have a nonlinear component (e.g., perspective and frustum maps)
123  /// have position-dependent voxel sizes.
124  Vec3d voxelSize(const Vec3d& xyz) const { return mMap->voxelSize(xyz); }
125 
126  /// Return the voxel volume of the linear component of the map.
127  double voxelVolume() const { return mMap->determinant(); }
128  /// Return the voxel volume at position (x, y, z).
129  double voxelVolume(const Vec3d& xyz) const { return mMap->determinant(xyz); }
130  /// Return true if the voxels in world space are uniformly sized cubes
131  bool hasUniformScale() const { return mMap->hasUniformScale(); }
132 
133  //@{
134  /// @brief Apply this transformation to the given coordinates.
135  Vec3d indexToWorld(const Vec3d& xyz) const { return mMap->applyMap(xyz); }
136  Vec3d indexToWorld(const Coord& ijk) const { return mMap->applyMap(ijk.asVec3d()); }
137  Vec3d worldToIndex(const Vec3d& xyz) const { return mMap->applyInverseMap(xyz); }
138  Coord worldToIndexCellCentered(const Vec3d& xyz) const {return Coord::round(worldToIndex(xyz));}
139  Coord worldToIndexNodeCentered(const Vec3d& xyz) const {return Coord::floor(worldToIndex(xyz));}
140  //@}
141 
142  //@{
143  /// @brief Apply this transformation to the given index-space bounding box.
144  /// @return an axis-aligned world-space bounding box
145  BBoxd indexToWorld(const CoordBBox&) const;
146  BBoxd indexToWorld(const BBoxd&) const;
147  //@}
148  //@{
149  /// @brief Apply the inverse of this transformation to the given world-space bounding box.
150  /// @return an axis-aligned index-space bounding box
151  BBoxd worldToIndex(const BBoxd&) const;
152  CoordBBox worldToIndexCellCentered(const BBoxd&) const;
153  CoordBBox worldToIndexNodeCentered(const BBoxd&) const;
154  //@}
155 
156  //@{
157  /// Return a base pointer to the transformation map.
158  MapBase::ConstPtr baseMap() const { return mMap; }
159  MapBase::Ptr baseMap() { return mMap; }
160  //@}
161 
162  //@{
163  /// @brief Return the result of downcasting the base map pointer to a
164  /// @c MapType pointer, or return a null pointer if the types are incompatible.
165  template<typename MapType> typename MapType::Ptr map();
166  template<typename MapType> typename MapType::ConstPtr map() const;
167  template<typename MapType> typename MapType::ConstPtr constMap() const;
168  //@}
169 
170  /// Unserialize this transform from the given stream.
171  void read(std::istream&);
172  /// Serialize this transform to the given stream.
173  void write(std::ostream&) const;
174 
175  /// @brief Print a description of this transform.
176  /// @param os a stream to which to write textual information
177  /// @param indent a string with which to prefix each line of text
178  void print(std::ostream& os = std::cout, const std::string& indent = "") const;
179 
180  bool operator==(const Transform& other) const;
181  inline bool operator!=(const Transform& other) const { return !(*this == other); }
182 
183 private:
184  MapBase::Ptr mMap;
185 }; // class Transform
186 
187 
188 OPENVDB_API std::ostream& operator<<(std::ostream&, const Transform&);
189 
190 
191 ////////////////////////////////////////
192 
193 
194 template<typename MapType>
195 inline typename MapType::Ptr
197 {
198  if (mMap->type() == MapType::mapType()) {
199  return StaticPtrCast<MapType>(mMap);
200  }
201  return typename MapType::Ptr();
202 }
203 
204 
205 template<typename MapType>
206 inline typename MapType::ConstPtr
208 {
209  return ConstPtrCast<const MapType>(
210  const_cast<Transform*>(this)->map<MapType>());
211 }
212 
213 
214 template<typename MapType>
215 inline typename MapType::ConstPtr
217 {
218  return map<MapType>();
219 }
220 
221 
222 ////////////////////////////////////////
223 
224 
225 /// Helper function used internally by processTypedMap()
226 template<typename ResolvedMapType, typename OpType>
227 inline void
229 {
230  ResolvedMapType& resolvedMap = *transform.map<ResolvedMapType>();
231 #ifdef _MSC_VER
232  op.operator()<ResolvedMapType>(resolvedMap);
233 #else
234  op.template operator()<ResolvedMapType>(resolvedMap);
235 #endif
236 }
237 
238 /// Helper function used internally by processTypedMap()
239 template<typename ResolvedMapType, typename OpType>
240 inline void
242 {
243  const ResolvedMapType& resolvedMap = *transform.map<ResolvedMapType>();
244 #ifdef _MSC_VER
245  op.operator()<ResolvedMapType>(resolvedMap);
246 #else
247  op.template operator()<ResolvedMapType>(resolvedMap);
248 #endif
249 }
250 
251 
252 /// @brief Utility function that, given a generic map pointer,
253 /// calls a functor on the fully-resoved map
254 ///
255 /// Usage:
256 /// @code
257 /// struct Foo {
258 /// template<typename MapT>
259 /// void operator()(const MapT& map) const { blah }
260 /// };
261 ///
262 /// processTypedMap(myMap, Foo());
263 /// @endcode
264 ///
265 /// @return @c false if the grid type is unknown or unhandled.
266 template<typename TransformType, typename OpType>
267 bool
268 processTypedMap(TransformType& transform, OpType& op)
269 {
270  using namespace openvdb;
271 
272  const Name mapType = transform.mapType();
273  if (mapType == UniformScaleMap::mapType()) {
274  doProcessTypedMap<UniformScaleMap, OpType>(transform, op);
275 
276  } else if (mapType == UniformScaleTranslateMap::mapType()) {
277  doProcessTypedMap<UniformScaleTranslateMap, OpType>(transform, op);
278 
279  } else if (mapType == ScaleMap::mapType()) {
280  doProcessTypedMap<ScaleMap, OpType>(transform, op);
281 
282  } else if (mapType == ScaleTranslateMap::mapType()) {
283  doProcessTypedMap<ScaleTranslateMap, OpType>(transform, op);
284 
285  } else if (mapType == UnitaryMap::mapType()) {
286  doProcessTypedMap<UnitaryMap, OpType>(transform, op);
287 
288  } else if (mapType == AffineMap::mapType()) {
289  doProcessTypedMap<AffineMap, OpType>(transform, op);
290 
291  } else if (mapType == TranslationMap::mapType()) {
292  doProcessTypedMap<TranslationMap, OpType>(transform, op);
293 
294  } else if (mapType == NonlinearFrustumMap::mapType()) {
295  doProcessTypedMap<NonlinearFrustumMap, OpType>(transform, op);
296  } else {
297  return false;
298  }
299  return true;
300 }
301 
302 } // namespace math
303 } // namespace OPENVDB_VERSION_NAME
304 } // namespace openvdb
305 
306 #endif // OPENVDB_MATH_TRANSFORM_HAS_BEEN_INCLUDED
307 
308 // Copyright (c) 2012-2018 DreamWorks Animation LLC
309 // All rights reserved. This software is distributed under the
310 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
bool operator!=(const Transform &other) const
Definition: Transform.h:181
Definition: ImfName.h:53
static Name mapType()
Return NonlinearFrustumMap.
Definition: Maps.h:2056
Vec3d indexToWorld(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:135
bool hasUniformScale() const
Return true if the voxels in world space are uniformly sized cubes.
Definition: Transform.h:131
SharedPtr< const Transform > ConstPtr
Definition: Transform.h:70
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:720
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition: Maps.h:685
bool isIdentity(const MatType &m)
Determine if a matrix is an identity matrix.
Definition: Mat.h:892
MapBase::ConstPtr baseMap() const
Return a base pointer to the transformation map.
Definition: Transform.h:158
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:189
SharedPtr< const MapBase > ConstPtr
Definition: Maps.h:165
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
void read(T &in, bool &v)
Definition: ImfXdr.h:611
MapType::ConstPtr constMap() const
Return the result of downcasting the base map pointer to a MapType pointer, or return a null pointer ...
Definition: Transform.h:216
std::shared_ptr< T > SharedPtr
Definition: Types.h:139
double voxelVolume() const
Return the voxel volume of the linear component of the map.
Definition: Transform.h:127
Vec3d voxelSize() const
Return the size of a voxel using the linear component of the map.
Definition: Transform.h:120
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glcorearb.h:475
MapType::Ptr map()
Return the result of downcasting the base map pointer to a MapType pointer, or return a null pointer ...
Definition: Transform.h:196
Vec3d voxelSize(const Vec3d &xyz) const
Return the size of a voxel at position (x, y, z).
Definition: Transform.h:124
Name mapType() const
Return the transformation map's type-name.
Definition: Transform.h:93
OPENVDB_API void calculateBounds(const Transform &t, const Vec3d &minWS, const Vec3d &maxWS, Vec3d &minIS, Vec3d &maxIS)
Calculate an axis-aligned bounding box in index space from an axis-aligned bounding box in world spac...
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
void doProcessTypedMap(Transform &transform, OpType &op)
Helper function used internally by processTypedMap()
Definition: Transform.h:228
Coord worldToIndexNodeCentered(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:139
GA_API const UT_StringHolder transform
int floor(T x)
Definition: ImathFun.h:150
double voxelVolume(const Vec3d &xyz) const
Return the voxel volume at position (x, y, z).
Definition: Transform.h:129
static Name mapType()
Return UnitaryMap.
Definition: Maps.h:1731
Vec3d indexToWorld(const Coord &ijk) const
Apply this transformation to the given coordinates.
Definition: Transform.h:136
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:138
MapBase::Ptr baseMap()
Return a base pointer to the transformation map.
Definition: Transform.h:159
bool isLinear() const
Return true if the transformation map is exclusively linear/affine.
Definition: Transform.h:88
Vec3d worldToIndex(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:137
void write(T &out, bool v)
Definition: ImfXdr.h:332
Abstract base class for maps.
Definition: Maps.h:161
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:135
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:488
bool processTypedMap(TransformType &transform, OpType &op)
Utility function that, given a generic map pointer, calls a functor on the fully-resoved map...
Definition: Transform.h:268
std::ostream & operator<<(std::ostream &os, const BBox< Vec3T > &b)
Definition: BBox.h:440