Mapping.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2016 Imperial College London
5  * Copyright 2013-2016 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_Mapping_H
21 #define MIRTK_Mapping_H
22 
23 #include "mirtk/Object.h"
24 
25 #include "mirtk/Point.h"
26 #include "mirtk/Cfstream.h"
27 #include "mirtk/ImageAttributes.h"
28 
29 #include "vtkSmartPointer.h"
30 #include "vtkPointSet.h"
31 
32 
33 namespace mirtk {
34 
35 
36 // Forward declaration of possible output map type
37 template <class TVoxel> class GenericImage;
38 
39 
40 /**
41  * Surface map or volumetric map
42  *
43  * A mapping assigns either each point of a surface embedded in 3D Euclidean
44  * space (a 2D manifold) or each point of a 3D volume a n-D target value,
45  * where n is usually 1, 2, or 3.
46  *
47  * It may represent an embedding of a cortical surface mesh, a bijective map of
48  * a surface to a disk, square, or sphere, as well as a bijective map from one
49  * piecewise linear complex (PLC) to another, such as the mapping of the brain
50  * volume to the unit ball (i.e., the interior of the unit sphere). An example
51  * of a surface map from computer graphics is the assignment of 2D texture
52  * coordinates to every vertex of the input mesh with linear interpolation
53  * within each triangle to map a 2D texture onto the surface.
54  *
55  * A bijective mapping is a reparameterization of the input domain, where the
56  * parameterization depends on the method used to compute the respective map.
57  */
58 class Mapping : public Object
59 {
60  mirtkAbstractMacro(Mapping);
61 
62  // ---------------------------------------------------------------------------
63  // Attributes
64 
65  /// Value assigned to points outside the map domain
66  mirtkPublicAttributeMacro(double, OutsideValue);
67 
68  /// Copy attributes of this class from another instance
69  void CopyAttributes(const Mapping &);
70 
71  // ---------------------------------------------------------------------------
72  // Construction/Destruction
73 
74 protected:
75 
76  /// Default constructor
77  Mapping();
78 
79  /// Copy constructor
80  Mapping(const Mapping &);
81 
82  /// Assignment operator
83  Mapping &operator =(const Mapping &);
84 
85 public:
86 
87  /// Read mapping from file
88  static Mapping *New(const char *);
89 
90  /// Destructor
91  virtual ~Mapping();
92 
93  /// Initialize map after inputs and parameters are set
94  virtual void Initialize();
95 
96  /// Make deep copy of this map
97  virtual Mapping *NewCopy() const = 0;
98 
99  // ---------------------------------------------------------------------------
100  // Map domain
101 
102  /// Dimension of map domain
103  virtual int NumberOfArguments() const;
104 
105  /// Get minimum axes-aligned bounding box of map domain
106  ///
107  /// \param[out] x1 Lower bound of map domain along x axis.
108  /// \param[out] y1 Lower bound of map domain along y axis.
109  /// \param[out] x2 Upper bound of map domain along x axis.
110  /// \param[out] y2 Upper bound of map domain along y axis.
111  void BoundingBox(double &x1, double &y1,
112  double &x2, double &y2) const;
113 
114  /// Get minimum axes-aligned bounding box of map domain
115  ///
116  /// \param[out] x1 Lower bound of map domain along x axis.
117  /// \param[out] y1 Lower bound of map domain along y axis.
118  /// \param[out] z1 Lower bound of map domain along z axis.
119  /// \param[out] x2 Upper bound of map domain along x axis.
120  /// \param[out] y2 Upper bound of map domain along y axis.
121  /// \param[out] z2 Upper bound of map domain along z axis.
122  virtual void BoundingBox(double &x1, double &y1, double &z1,
123  double &x2, double &y2, double &z2) const = 0;
124 
125  /// Get minimum axes-aligned bounding box of input domain
126  ///
127  /// \param[out] bounds Bounds of input domain in VTK order, i.e.,
128  /// [x1, x2, y1, y2, z1, z2].
129  void BoundingBox(double bounds[6]) const;
130 
131  /// Get minimum axes-aligned bounding box of input domain
132  ///
133  /// \param[out] p1 Lower-left-front corner of input domain bounding box.
134  /// \param[out] p2 Upper-right-back corner of input domain bounding box.
135  void BoundingBox(Point &p1, Point &p2) const;
136 
137  /// Get regular lattice attributes of map domain
138  ///
139  /// \param[in] nx Number of lattice points along x axis.
140  /// \param[in] ny Number of lattice points along y axis.
141  /// \param[in] nz Number of lattice points along z axis.
142  ImageAttributes Attributes(int nx, int ny = 0, int nz = 0) const;
143 
144  /// Get regular lattice attributes of map domain
145  ///
146  /// If no lattice spacing is specified, the length of the bounding box
147  /// diagonal dividied by 256 is used.
148  ///
149  /// \param[in] dx Lattice spacing along x axis.
150  /// \param[in] dy Lattice spacing along y axis.
151  /// \param[in] dz Lattice spacing along z axis.
152  ImageAttributes Attributes(double dx = .0, double dy = .0, double dz = .0) const;
153 
154  // ---------------------------------------------------------------------------
155  // Evaluation
156 
157  /// Dimension of codomain, i.e., number of output values
158  virtual int NumberOfComponents() const = 0;
159 
160  /// Evaluate map at a given point
161  ///
162  /// \param[out] v Map value.
163  /// \param[in] x Coordinate of point along x axis at which to evaluate map.
164  /// \param[in] y Coordinate of point along y axis at which to evaluate map.
165  /// \param[in] z Coordinate of point along z axis at which to evaluate map.
166  ///
167  /// \returns Whether input point is inside map domain.
168  virtual bool Evaluate(double *v, double x, double y, double z = 0) const = 0;
169 
170  /// Evaluate map at a given point
171  ///
172  /// \param[out] v Map value.
173  /// \param[in] p Point at which to evaluate map.
174  ///
175  /// \returns Whether input point is inside map domain.
176  bool Evaluate(double *v, const double p[3]) const;
177 
178  /// Evaluate map at a given point
179  ///
180  /// \param[out] v Map value.
181  /// \param[in] p Point at which to evaluate map.
182  ///
183  /// \returns Whether input point is inside map domain.
184  bool Evaluate(double *v, const Point &p) const;
185 
186  /// Evaluate map at a given point
187  ///
188  /// \param[in] x Coordinate of point along x axis at which to evaluate map.
189  /// \param[in] y Coordinate of point along y axis at which to evaluate map.
190  /// \param[in] z Coordinate of point along z axis at which to evaluate map.
191  /// \param[in] l Index of map value component.
192  ///
193  /// \returns The l-th component of the map value evaluated at the given point
194  /// or the \c OutsideValue when input point is outside the map domain.
195  virtual double Evaluate(double x, double y, double z = 0, int l = 0) const;
196 
197  /// Evaluate map at a given point
198  ///
199  /// \param[in] p Point at which to evaluate map.
200  /// \param[in] l Index of map value component.
201  ///
202  /// \returns The l-th component of the map value evaluated at the given point
203  /// or the \c OutsideValue when input point is outside the map domain.
204  double Evaluate(const double p[3], int l = 0) const;
205 
206  /// Evaluate map at a given point
207  ///
208  /// \param[in] p Point at which to evaluate map.
209  /// \param[in] l Index of map value component.
210  ///
211  /// \returns The l-th component of the map value evaluated at the given point
212  /// or the \c OutsideValue when input point is outside the map domain.
213  double Evaluate(const Point &, int l = 0) const;
214 
215  /// Evaluate map at each point of a regular lattice
216  ///
217  /// \param[out] f Defines lattice on which to evaluate the map. The map value
218  /// at each lattice point is stored at the respective voxel.
219  /// The number of map values stored in the output image is
220  /// determined by the temporal dimension of the image.
221  /// \param[in] l Index of first map value component to store in output image.
222  /// \param[in] m Piecewise linear complex (PLC) defining an arbitrary subset
223  /// of the lattice points at which to evaluate the map.
224  virtual void Evaluate(GenericImage<float> &f, int l = 0, vtkSmartPointer<vtkPointSet> m = nullptr) const;
225 
226  /// Evaluate map at each point of a regular lattice
227  ///
228  /// \param[out] f Defines lattice on which to evaluate the map. The map value
229  /// at each lattice point is stored at the respective voxel.
230  /// The number of map values stored in the output image is
231  /// determined by the temporal dimension of the image.
232  /// \param[in] l Index of first map value component to store in output image.
233  /// \param[in] m Piecewise linear complex (PLC) defining an arbitrary subset
234  /// of the lattice points at which to evaluate the map.
235  virtual void Evaluate(GenericImage<double> &f, int l = 0, vtkSmartPointer<vtkPointSet> m = nullptr) const;
236 
237  // ---------------------------------------------------------------------------
238  // I/O
239 
240  /// Read map from file
241  virtual bool Read(const char *);
242 
243  /// Write map to file
244  virtual bool Write(const char *) const;
245 
246 protected:
247 
248  /// Read map attributes and parameters from file stream
249  virtual void ReadMap(Cifstream &);
250 
251  /// Write map attributes and parameters to file stream
252  virtual void WriteMap(Cofstream &) const;
253 
254 };
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 // Inline definitions
258 ////////////////////////////////////////////////////////////////////////////////
259 
260 // =============================================================================
261 // Map domain
262 // =============================================================================
263 
264 // -----------------------------------------------------------------------------
265 inline int Mapping::NumberOfArguments() const
266 {
267  double x1, y1, z1, x2, y2, z2;
268  this->BoundingBox(x1, y1, z1, x2, y2, z2);
269  return (z1 == z2 ? ((y1 == y2) ? 1 : 2) : 3);
270 }
271 
272 // -----------------------------------------------------------------------------
273 inline void Mapping::BoundingBox(double &x1, double &y1, double &x2, double &y2) const
274 {
275  double z1, z2;
276  this->BoundingBox(x1, y1, z1, x2, y2, z2);
277 }
278 
279 // -----------------------------------------------------------------------------
280 inline void Mapping::BoundingBox(double bounds[6]) const
281 {
282  this->BoundingBox(bounds[0], bounds[2], bounds[4],
283  bounds[1], bounds[3], bounds[5]);
284 }
285 
286 // -----------------------------------------------------------------------------
287 inline void Mapping::BoundingBox(Point &p1, Point &p2) const
288 {
289  this->BoundingBox(p1._x, p1._y, p1._z, p2._x, p2._y, p2._z);
290 }
291 
292 // =============================================================================
293 // Evaluation
294 // =============================================================================
295 
296 // -----------------------------------------------------------------------------
297 inline bool Mapping::Evaluate(double *v, const double p[3]) const
298 {
299  return this->Evaluate(v, p[0], p[1], p[2]);
300 }
301 
302 // -----------------------------------------------------------------------------
303 inline bool Mapping::Evaluate(double *v, const Point &p) const
304 {
305  return this->Evaluate(v, p._x, p._y, p._z);
306 }
307 
308 // -----------------------------------------------------------------------------
309 inline double Mapping::Evaluate(double x, double y, double z, int l) const
310 {
311  double * const v = new double[this->NumberOfComponents()];
312  this->Evaluate(v, x, y, z);
313  const double s = v[l];
314  delete[] v;
315  return s;
316 }
317 
318 // -----------------------------------------------------------------------------
319 inline double Mapping::Evaluate(const double p[3], int l) const
320 {
321  return this->Evaluate(p[0], p[1], p[2], l);
322 }
323 
324 // -----------------------------------------------------------------------------
325 inline double Mapping::Evaluate(const Point &p, int l) const
326 {
327  return this->Evaluate(p._x, p._y, p._z, l);
328 }
329 
330 
331 } // namespace mirtk
332 
333 #endif // MIRTK_Mapping_H
void BoundingBox(double &x1, double &y1, double &x2, double &y2) const
Definition: Mapping.h:273
virtual int NumberOfArguments() const
Dimension of map domain.
Definition: Mapping.h:265
virtual void WriteMap(Cofstream &) const
Write map attributes and parameters to file stream.
virtual int NumberOfComponents() const =0
Dimension of codomain, i.e., number of output values.
virtual bool Evaluate(double *v, double x, double y, double z=0) const =0
static Mapping * New(const char *)
Read mapping from file.
double _x
x coordinate of Point
Definition: Point.h:46
ImageAttributes Attributes(int nx, int ny=0, int nz=0) const
virtual Mapping * NewCopy() const =0
Make deep copy of this map.
Mapping & operator=(const Mapping &)
Assignment operator.
Mapping()
Default constructor.
virtual bool Read(const char *)
Read map from file.
Definition: IOConfig.h:41
virtual bool Write(const char *) const
Write map to file.
virtual void ReadMap(Cifstream &)
Read map attributes and parameters from file stream.
double _z
z coordinate of Point
Definition: Point.h:48
virtual void Initialize()
Initialize map after inputs and parameters are set.
double _y
y coordinate of Point
Definition: Point.h:47
virtual ~Mapping()
Destructor.