OpenVDB 11.0.0
Loading...
Searching...
No Matches
Transform.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3
4#ifndef OPENVDB_MATH_TRANSFORM_HAS_BEEN_INCLUDED
5#define OPENVDB_MATH_TRANSFORM_HAS_BEEN_INCLUDED
6
7#include "Maps.h"
8#include <openvdb/Types.h>
9#include <iosfwd>
10
11namespace openvdb {
13namespace OPENVDB_VERSION_NAME {
14namespace math {
15
16// Forward declaration
17class Transform;
18
19
20// Utility methods
21
22/// @brief Calculate an axis-aligned bounding box in index space from an
23/// axis-aligned bounding box in world space.
24/// @see Transform::worldToIndex(const BBoxd&) const
25OPENVDB_API void
26calculateBounds(const Transform& t, const Vec3d& minWS, const Vec3d& maxWS,
27 Vec3d& minIS, Vec3d& maxIS);
28
29/// @todo Calculate an axis-aligned bounding box in index space from a
30/// bounding sphere in world space.
31//void calculateBounds(const Transform& t, const Vec3d& center, const Real radius,
32// Vec3d& minIS, Vec3d& maxIS);
33
34
35////////////////////////////////////////
36
37
38/// @class Transform
40{
41public:
44
45 Transform(): mMap(MapBase::Ptr(new ScaleMap())) {}
49
50 Ptr copy() const { return Ptr(new Transform(mMap->copy())); }
51
52 //@{
53 /// @brief Create and return a shared pointer to a new transform.
54 static Transform::Ptr createLinearTransform(double voxelSize = 1.0);
56 static Transform::Ptr createFrustumTransform(const BBoxd&, double taper,
57 double depth, double voxelSize = 1.0);
58 //@}
59
60 /// Return @c true if the transformation map is exclusively linear/affine.
61 bool isLinear() const { return mMap->isLinear(); }
62
63 /// Return @c true if the transform is equivalent to an idenity.
64 bool isIdentity() const ;
65 /// Return the transformation map's type-name
66 Name mapType() const { return mMap->type(); }
67
68
69 //@{
70 /// @brief Update the linear (affine) map by prepending or
71 /// postfixing the appropriate operation. In the case of
72 /// a frustum, the pre-operations apply to the linear part
73 /// of the transform and not the entire transform, while the
74 /// post-operations are allways applied last.
75 void preRotate(double radians, const Axis axis = X_AXIS);
76 void preTranslate(const Vec3d&);
77 void preScale(const Vec3d&);
78 void preScale(double);
79 void preShear(double shear, Axis axis0, Axis axis1);
80 void preMult(const Mat4d&);
81 void preMult(const Mat3d&);
82
83 void postRotate(double radians, const Axis axis = X_AXIS);
84 void postTranslate(const Vec3d&);
85 void postScale(const Vec3d&);
86 void postScale(double);
87 void postShear(double shear, Axis axis0, Axis axis1);
88 void postMult(const Mat4d&);
89 void postMult(const Mat3d&);
90 //@}
91
92 /// Return the size of a voxel using the linear component of the map.
93 Vec3d voxelSize() const { return mMap->voxelSize(); }
94 /// @brief Return the size of a voxel at position (x, y, z).
95 /// @note Maps that have a nonlinear component (e.g., perspective and frustum maps)
96 /// have position-dependent voxel sizes.
97 Vec3d voxelSize(const Vec3d& xyz) const { return mMap->voxelSize(xyz); }
98
99 /// Return the voxel volume of the linear component of the map.
100 double voxelVolume() const { return mMap->determinant(); }
101 /// Return the voxel volume at position (x, y, z).
102 double voxelVolume(const Vec3d& xyz) const { return mMap->determinant(xyz); }
103 /// Return true if the voxels in world space are uniformly sized cubes
104 bool hasUniformScale() const { return mMap->hasUniformScale(); }
105
106 //@{
107 /// @brief Apply this transformation to the given coordinates.
108 Vec3d indexToWorld(const Vec3d& xyz) const { return mMap->applyMap(xyz); }
109 Vec3d indexToWorld(const Coord& ijk) const { return mMap->applyMap(ijk.asVec3d()); }
110 Vec3d worldToIndex(const Vec3d& xyz) const { return mMap->applyInverseMap(xyz); }
111 Coord worldToIndexCellCentered(const Vec3d& xyz) const {return Coord::round(worldToIndex(xyz));}
112 Coord worldToIndexNodeCentered(const Vec3d& xyz) const {return Coord::floor(worldToIndex(xyz));}
113 //@}
114
115 //@{
116 /// @brief Apply this transformation to the given index-space bounding box.
117 /// @return an axis-aligned world-space bounding box
119 BBoxd indexToWorld(const BBoxd&) const;
120 //@}
121 //@{
122 /// @brief Apply the inverse of this transformation to the given world-space bounding box.
123 /// @return an axis-aligned index-space bounding box
124 BBoxd worldToIndex(const BBoxd&) const;
127 //@}
128
129 //@{
130 /// Return a base pointer to the transformation map.
131 MapBase::ConstPtr baseMap() const { return mMap; }
132 MapBase::Ptr baseMap() { return mMap; }
133 //@}
134
135 //@{
136 /// @brief Return the result of downcasting the base map pointer to a
137 /// @c MapType pointer, or return a null pointer if the types are incompatible.
138 template<typename MapType> typename MapType::Ptr map();
139 template<typename MapType> typename MapType::ConstPtr map() const;
140 template<typename MapType> typename MapType::ConstPtr constMap() const;
141 //@}
142
143 /// Unserialize this transform from the given stream.
144 void read(std::istream&);
145 /// Serialize this transform to the given stream.
146 void write(std::ostream&) const;
147
148 /// @brief Print a description of this transform.
149 /// @param os a stream to which to write textual information
150 /// @param indent a string with which to prefix each line of text
151 void print(std::ostream& os = std::cout, const std::string& indent = "") const;
152
153 bool operator==(const Transform& other) const;
154 inline bool operator!=(const Transform& other) const { return !(*this == other); }
155
156private:
157 MapBase::Ptr mMap;
158}; // class Transform
159
160
161OPENVDB_API std::ostream& operator<<(std::ostream&, const Transform&);
162
163
164////////////////////////////////////////
165
166
167template<typename MapType>
168inline typename MapType::Ptr
169Transform::map()
170{
171 if (mMap->type() == MapType::mapType()) {
172 return StaticPtrCast<MapType>(mMap);
173 }
174 return typename MapType::Ptr();
175}
176
177
178template<typename MapType>
179inline typename MapType::ConstPtr
180Transform::map() const
181{
182 return ConstPtrCast<const MapType>(
183 const_cast<Transform*>(this)->map<MapType>());
184}
185
186
187template<typename MapType>
188inline typename MapType::ConstPtr
189Transform::constMap() const
190{
191 return map<MapType>();
192}
193
194
195////////////////////////////////////////
196
197
198/// Helper function used internally by processTypedMap()
199template<typename ResolvedMapType, typename OpType>
200inline void
201doProcessTypedMap(Transform& transform, OpType& op)
202{
203 ResolvedMapType& resolvedMap = *transform.map<ResolvedMapType>();
204 op.template operator()<ResolvedMapType>(resolvedMap);
205}
206
207/// Helper function used internally by processTypedMap()
208template<typename ResolvedMapType, typename OpType>
209inline void
210doProcessTypedMap(const Transform& transform, OpType& op)
211{
212 const ResolvedMapType& resolvedMap = *transform.map<ResolvedMapType>();
213 op.template operator()<ResolvedMapType>(resolvedMap);
214}
215
216
217/// @brief Utility function that, given a generic map pointer,
218/// calls a functor on the fully-resoved map
219///
220/// Usage:
221/// @code
222/// struct Foo {
223/// template<typename MapT>
224/// void operator()(const MapT& map) const { blah }
225/// };
226///
227/// processTypedMap(myMap, Foo());
228/// @endcode
229///
230/// @return @c false if the grid type is unknown or unhandled.
231template<typename TransformType, typename OpType>
232bool
233processTypedMap(TransformType& transform, OpType& op)
234{
235 using namespace openvdb;
236
237 const Name mapType = transform.mapType();
238 if (mapType == UniformScaleMap::mapType()) {
239 doProcessTypedMap<UniformScaleMap, OpType>(transform, op);
240
241 } else if (mapType == UniformScaleTranslateMap::mapType()) {
242 doProcessTypedMap<UniformScaleTranslateMap, OpType>(transform, op);
243
244 } else if (mapType == ScaleMap::mapType()) {
245 doProcessTypedMap<ScaleMap, OpType>(transform, op);
246
247 } else if (mapType == ScaleTranslateMap::mapType()) {
248 doProcessTypedMap<ScaleTranslateMap, OpType>(transform, op);
249
250 } else if (mapType == UnitaryMap::mapType()) {
251 doProcessTypedMap<UnitaryMap, OpType>(transform, op);
252
253 } else if (mapType == AffineMap::mapType()) {
254 doProcessTypedMap<AffineMap, OpType>(transform, op);
255
256 } else if (mapType == TranslationMap::mapType()) {
257 doProcessTypedMap<TranslationMap, OpType>(transform, op);
258
259 } else if (mapType == NonlinearFrustumMap::mapType()) {
260 doProcessTypedMap<NonlinearFrustumMap, OpType>(transform, op);
261 } else {
262 return false;
263 }
264 return true;
265}
266
267} // namespace math
268} // namespace OPENVDB_VERSION_NAME
269} // namespace openvdb
270
271#endif // OPENVDB_MATH_TRANSFORM_HAS_BEEN_INCLUDED
#define OPENVDB_API
Definition Platform.h:274
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:251
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
Vec3d asVec3d() const
Definition Coord.h:143
Abstract base class for maps.
Definition Maps.h:135
SharedPtr< MapBase > Ptr
Definition Maps.h:137
SharedPtr< const MapBase > ConstPtr
Definition Maps.h:138
A specialized Affine transform that scales along the principal axis the scaling need not be uniform i...
Definition Maps.h:656
Definition Transform.h:40
BBoxd worldToIndex(const BBoxd &) const
Apply the inverse of this transformation to the given world-space bounding box.
bool operator!=(const Transform &other) const
Definition Transform.h:154
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Definition Transform.h:111
Name mapType() const
Return the transformation map's type-name.
Definition Transform.h:66
bool isLinear() const
Return true if the transformation map is exclusively linear/affine.
Definition Transform.h:61
void preTranslate(const Vec3d &)
BBoxd indexToWorld(const CoordBBox &) const
Apply this transformation to the given index-space bounding box.
double voxelVolume() const
Return the voxel volume of the linear component of the map.
Definition Transform.h:100
void postMult(const Mat3d &)
void print(std::ostream &os=std::cout, const std::string &indent="") const
Print a description of this transform.
Vec3d indexToWorld(const Coord &ijk) const
Definition Transform.h:109
Vec3d voxelSize() const
Return the size of a voxel using the linear component of the map.
Definition Transform.h:93
Transform(const Transform &)
void postRotate(double radians, const Axis axis=X_AXIS)
Vec3d indexToWorld(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition Transform.h:108
CoordBBox worldToIndexNodeCentered(const BBoxd &) const
Ptr copy() const
Definition Transform.h:50
Vec3d worldToIndex(const Vec3d &xyz) const
Definition Transform.h:110
void write(std::ostream &) const
Serialize this transform to the given stream.
void preScale(const Vec3d &)
void postMult(const Mat4d &)
MapBase::Ptr baseMap()
Definition Transform.h:132
SharedPtr< const Transform > ConstPtr
Definition Transform.h:43
void preRotate(double radians, const Axis axis=X_AXIS)
Update the linear (affine) map by prepending or postfixing the appropriate operation....
Transform(const MapBase::Ptr &)
Vec3d voxelSize(const Vec3d &xyz) const
Return the size of a voxel at position (x, y, z).
Definition Transform.h:97
void read(std::istream &)
Unserialize this transform from the given stream.
~Transform()
Definition Transform.h:48
Transform()
Definition Transform.h:45
BBoxd indexToWorld(const BBoxd &) const
void postTranslate(const Vec3d &)
bool hasUniformScale() const
Return true if the voxels in world space are uniformly sized cubes.
Definition Transform.h:104
static Transform::Ptr createLinearTransform(const Mat4R &)
bool operator==(const Transform &other) const
bool isIdentity() const
Return true if the transform is equivalent to an idenity.
CoordBBox worldToIndexCellCentered(const BBoxd &) const
Coord worldToIndexNodeCentered(const Vec3d &xyz) const
Definition Transform.h:112
MapType::Ptr map()
Return the result of downcasting the base map pointer to a MapType pointer, or return a null pointer ...
Definition Transform.h:169
void postScale(const Vec3d &)
SharedPtr< Transform > Ptr
Definition Transform.h:42
void preMult(const Mat4d &)
void preShear(double shear, Axis axis0, Axis axis1)
static Transform::Ptr createLinearTransform(double voxelSize=1.0)
Create and return a shared pointer to a new transform.
MapBase::ConstPtr baseMap() const
Return a base pointer to the transformation map.
Definition Transform.h:131
double voxelVolume(const Vec3d &xyz) const
Return the voxel volume at position (x, y, z).
Definition Transform.h:102
void postShear(double shear, Axis axis0, Axis axis1)
static Transform::Ptr createFrustumTransform(const BBoxd &, double taper, double depth, double voxelSize=1.0)
void preMult(const Mat3d &)
Definition Vec3.h:24
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...
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:233
void doProcessTypedMap(Transform &transform, OpType &op)
Helper function used internally by processTypedMap()
Definition Transform.h:201
Axis
Definition Math.h:901
std::string Name
Definition Name.h:19
std::ostream & operator<<(std::ostream &ostr, const Metadata &metadata)
Write a Metadata to an output stream.
Definition Metadata.h:351
std::shared_ptr< T > SharedPtr
Definition Types.h:114
Definition Exceptions.h:13
#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