PiecewiseLinearMap.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2015-2016 Imperial College London
5  * Copyright 2015-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_PiecewiseLinearMap_H
21 #define MIRTK_PiecewiseLinearMap_H
22 
23 #include "mirtk/Mapping.h"
24 #include "mirtk/Point.h"
25 
26 #include "vtkSmartPointer.h"
27 #include "vtkDataSet.h"
28 #include "vtkDataArray.h"
29 #include "vtkAbstractCellLocator.h"
30 
31 
32 namespace mirtk {
33 
34 
35 /**
36  * Piecewise linear map defined at mesh nodes
37  *
38  * This map is defined by its values at discrete mesh nodes.
39  * Intermediate values are interpolated using the weights of the respective
40  * mesh cell which this point belongs to. If the point is not contained in
41  * any mesh cell, the point is mapped to a constant outside value.
42  *
43  * A surface map is commonly represented by the texture coordinates of a
44  * triangular surface mesh, while a tetrahedral mesh is commonly used to
45  * parameterize a volumetric map. These maps are usually computed using a
46  * finite element method (FEM).
47  */
49 {
50  mirtkObjectMacro(PiecewiseLinearMap);
51 
52  // ---------------------------------------------------------------------------
53  // Attributes
54 
55  /// Mesh which discretizes the domain of this piecewise linear map
56  mirtkPublicAttributeMacro(vtkSmartPointer<vtkDataSet>, Domain);
57 
58  /// Point data array with map values at mesh points
59  mirtkPublicAttributeMacro(vtkSmartPointer<vtkDataArray>, Values);
60 
61  /// Locates cell within which a given point lies
62  mirtkAttributeMacro(vtkSmartPointer<vtkAbstractCellLocator>, Locator);
63 
64  /// Maximum number cell points
65  mirtkAttributeMacro(int, MaxCellSize);
66 
67  /// Squared distance tolerance used to locate cells
68  /// \note Unused argument of vtkCellLocator::FindCell (as of VTK <= 7.0).
69  static const double _Tolerance2;
70 
71  /// Copy attributes of this class from another instance
72  void CopyAttributes(const PiecewiseLinearMap &);
73 
74  // ---------------------------------------------------------------------------
75  // Construction/Destruction
76 
77 public:
78 
79  /// Default constructor
81 
82  /// Copy constructor
84 
85  /// Assignment operator
87 
88  /// Initialize map after inputs and parameters are set
89  virtual void Initialize();
90 
91  /// Make deep copy of this volumetric map
92  virtual Mapping *NewCopy() const;
93 
94  /// Destructor
95  virtual ~PiecewiseLinearMap();
96 
97  // ---------------------------------------------------------------------------
98  // Map domain
99 
100  // Import other overloads
101  using Mapping::BoundingBox;
102 
103  /// Number of discrete points at which map values are given
104  int NumberOfPoints() const;
105 
106  /// Get i-th domain mesh point
107  ///
108  /// \param[in] i Point index.
109  ///
110  /// \returns Point coordinates.
111  class Point Point(int i) const;
112 
113  /// Get i-th domain mesh point
114  ///
115  /// \param[in] i Point index.
116  /// \param[out] x Point coordinate along x axis.
117  /// \param[out] y Point coordinate along y axis.
118  void GetPoint(int i, double &x, double &y) const;
119 
120  /// Get i-th domain mesh point
121  ///
122  /// \param[in] i Point index.
123  /// \param[out] x Point coordinate along x axis.
124  /// \param[out] y Point coordinate along y axis.
125  /// \param[out] z Point coordinate along z axis.
126  void GetPoint(int i, double &x, double &y, double &z) const;
127 
128  /// Get i-th domain mesh point
129  ///
130  /// \param[in] i Point index.
131  /// \param[out] p Point coordinates.
132  void GetPoint(int i, double p[3]) const;
133 
134  /// Get minimum axes-aligned bounding box of map domain
135  ///
136  /// \param[out] x1 Lower bound of map domain along x axis.
137  /// \param[out] y1 Lower bound of map domain along y axis.
138  /// \param[out] z1 Lower bound of map domain along z axis.
139  /// \param[out] x2 Upper bound of map domain along x axis.
140  /// \param[out] y2 Upper bound of map domain along y axis.
141  /// \param[out] z2 Upper bound of map domain along z axis.
142  virtual void BoundingBox(double &x1, double &y1, double &z1,
143  double &x2, double &y2, double &z2) const;
144 
145  // ---------------------------------------------------------------------------
146  // Map codomain
147 
148  /// Dimension of codomain, i.e., number of output values
149  virtual int NumberOfComponents() const;
150 
151  /// Mesh discretizing the map domain with mapped mesh points
152  ///
153  /// \note Use this function only when the dimension of the codomain is 2 or 3.
154  ///
155  /// \sa NumberOfComponents.
156  ///
157  /// \returns Mesh discretizing the codomain of the map, where the mesh points
158  /// correspond to the unmapped points of the map domain mesh or nullptr
159  /// when the dimension of the codomain is not 2 or 3.
160  vtkSmartPointer<vtkDataSet> Codomain() const;
161 
162  // ---------------------------------------------------------------------------
163  // Evaluation
164 
165  // Import other overloads
166  using Mapping::Evaluate;
167 
168  /// Evaluate map at a given mesh point
169  ///
170  /// \param[in] i Point index.
171  /// \param[out] v Map value.
172  void GetValue(int i, double *v) const;
173 
174  /// Evaluate map at a given mesh point
175  ///
176  /// \param[in] i Point index.
177  /// \param[in] l Index of map value component.
178  ///
179  /// \returns The l-th component of the map value at the given mesh point.
180  double Value(int i, int l = 0) const;
181 
182  /// Evaluate map at a given point
183  ///
184  /// \param[out] v Map value.
185  /// \param[in] x Coordinate of point along x axis at which to evaluate map.
186  /// \param[in] y Coordinate of point along y axis at which to evaluate map.
187  /// \param[in] z Coordinate of point along z axis at which to evaluate map.
188  ///
189  /// \returns Whether input point is inside map domain.
190  virtual bool Evaluate(double *v, double x, double y, double z = 0) const;
191 
192  /// Evaluate map at a given point
193  ///
194  /// \param[in] x Coordinate of point along x axis at which to evaluate map.
195  /// \param[in] y Coordinate of point along y axis at which to evaluate map.
196  /// \param[in] z Coordinate of point along z axis at which to evaluate map.
197  /// \param[in] l Index of map value component.
198  ///
199  /// \returns The l-th component of the map value evaluate at the given point
200  /// or the \c OutsideValue when input point is outside the map domain.
201  virtual double Evaluate(double x, double y, double z = 0, int l = 0) const;
202 
203  // ---------------------------------------------------------------------------
204  // I/O
205 
206  /// Read map from file
207  virtual bool Read(const char *);
208 
209  /// Write map to file
210  virtual bool Write(const char *) const;
211 
212 };
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 // Inline definitions
216 ////////////////////////////////////////////////////////////////////////////////
217 
218 // -----------------------------------------------------------------------------
220 {
221  return static_cast<int>(_Domain->GetNumberOfPoints());
222 }
223 
224 // -----------------------------------------------------------------------------
225 inline void PiecewiseLinearMap::GetPoint(int i, double p[3]) const
226 {
227  _Domain->GetPoint(static_cast<vtkIdType>(i), p);
228 }
229 
230 // -----------------------------------------------------------------------------
231 inline void PiecewiseLinearMap::GetPoint(int i, double &x, double &y) const
232 {
233  double p[3];
234  _Domain->GetPoint(static_cast<vtkIdType>(i), p);
235  x = p[0], y = p[1];
236 }
237 
238 // -----------------------------------------------------------------------------
239 inline void PiecewiseLinearMap::GetPoint(int i, double &x, double &y, double &z) const
240 {
241  double p[3];
242  _Domain->GetPoint(static_cast<vtkIdType>(i), p);
243  x = p[0], y = p[1], z = p[2];
244 }
245 
246 // -----------------------------------------------------------------------------
247 inline Point PiecewiseLinearMap::Point(int i) const
248 {
249  double p[3];
250  this->GetPoint(i, p);
251  return p;
252 }
253 
254 // -----------------------------------------------------------------------------
255 inline void PiecewiseLinearMap::GetValue(int i, double *v) const
256 {
257  _Values->GetTuple(static_cast<vtkIdType>(i), v);
258 }
259 
260 // -----------------------------------------------------------------------------
261 inline double PiecewiseLinearMap::Value(int i, int l) const
262 {
263  return _Values->GetComponent(static_cast<vtkIdType>(i), l);
264 }
265 
266 
267 } // namespace mirtk
268 
269 #endif // MIRTK_PiecewiseLinearMap_H
void BoundingBox(double &x1, double &y1, double &x2, double &y2) const
Definition: Mapping.h:273
int NumberOfPoints() const
Number of discrete points at which map values are given.
virtual void BoundingBox(double &x1, double &y1, double &z1, double &x2, double &y2, double &z2) const
virtual ~PiecewiseLinearMap()
Destructor.
virtual bool Evaluate(double *v, double x, double y, double z=0) const =0
virtual void Initialize()
Initialize map after inputs and parameters are set.
Definition: IOConfig.h:41
virtual int NumberOfComponents() const
Dimension of codomain, i.e., number of output values.
void GetPoint(int i, double &x, double &y) const
vtkSmartPointer< vtkDataSet > Codomain() const
double Value(int i, int l=0) const
class Point Point(int i) const
virtual bool Evaluate(double *v, double x, double y, double z=0) const
PiecewiseLinearMap & operator=(const PiecewiseLinearMap &)
Assignment operator.
void GetValue(int i, double *v) const
PiecewiseLinearMap()
Default constructor.
virtual bool Read(const char *)
Read map from file.
virtual bool Write(const char *) const
Write map to file.
virtual Mapping * NewCopy() const
Make deep copy of this volumetric map.