SpectralConformalSurfaceMapper.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2016 Imperial College London
5  * Copyright 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_SpectralConformalSurfaceMapper_H
21 #define MIRTK_SpectralConformalSurfaceMapper_H
22 
23 #include "mirtk/FreeBoundarySurfaceMapper.h"
24 
25 #include "mirtk/Array.h"
26 
27 #include "vtkSmartPointer.h"
28 #include "vtkDataArray.h"
29 
30 
31 namespace mirtk {
32 
33 
34 /**
35  * Least squares conformal map without boundary constraints
36  *
37  * - Mullen et al. (2008). Spectral conformal parameterization.
38  * Eurographics Symposium on Geometry Processing, 27(5), 1487–1494.
39  *
40  * \todo Implement area weighting extension as described in Mullen et al. (2008)
41  * to account for irregular surface sampling.
42  */
44 {
45  mirtkObjectMacro(SpectralConformalSurfaceMapper);
46 
47  // ---------------------------------------------------------------------------
48  // Attributes
49 
50 private:
51 
52  /// Maximum number of iterations
53  ///
54  /// When the number of iterations is set to 1 a sparse direct solver is used.
55  mirtkPublicAttributeMacro(int, NumberOfIterations);
56 
57  /// Tolerance for sparse linear solver
58  mirtkPublicAttributeMacro(double, Tolerance);
59 
60  /// Index of point in set of points with free (i >= 0) or fixed (i < 0) values
61  mirtkAttributeMacro(Array<int>, PointIndex);
62 
63  /// IDs of surface points with free map values
64  mirtkAttributeMacro(Array<int>, FreePoints);
65 
66  /// IDs of surface points with fixed map values
67  mirtkAttributeMacro(Array<int>, FixedPoints);
68 
69  /// Map values at fixed points
70  mirtkAttributeMacro(Matrix, FixedValues);
71 
72  /// Computed map values at surface points
73  mirtkAttributeMacro(vtkSmartPointer<vtkDataArray>, Values);
74 
75  /// Copy attributes of this class from another instance
76  void CopyAttributes(const SpectralConformalSurfaceMapper &);
77 
78  // ---------------------------------------------------------------------------
79  // Construction/Destruction
80 
81 public:
82 
83  /// Default constructor
85 
86  /// Copy constructor
88 
89  /// Assignment operator
91 
92  /// Destructor
94 
95  // ---------------------------------------------------------------------------
96  // Constraints
97 
98  /// Add hard point constraint
99  ///
100  /// \param[in] i Surface point index.
101  /// \param[in] u First constraint value component.
102  /// \param[in] v Second constraint value component.
103  void AddFixedPoint(int i, double u, double v);
104 
105  // ---------------------------------------------------------------------------
106  // Execution
107 
108 protected:
109 
110  /// Weight of undirected edge (i, j)
111  ///
112  /// \param[in] i First end point.
113  /// \param[in] j Second end point.
114  ///
115  /// \returns Weight of undirected edge (i, j).
116  virtual double Weight(int i, int j) const;
117 
118  /// Initialize filter after input and parameters are set
119  virtual void Initialize();
120 
121  /// Compute surface map
122  virtual void ComputeMap();
123 
124  /// Finalize filter execution
125  virtual void Finalize();
126 
127  // ---------------------------------------------------------------------------
128  // Auxiliaries
129 
130 public:
131 
132  /// Number of surface points with free map value
133  int NumberOfFreePoints() const;
134 
135  /// Number of surface points with fixed map value
136  int NumberOfFixedPoints() const;
137 
138  /// Whether the map value of the specified surface point is free
139  bool IsFreePoint(int i) const;
140 
141  /// Whether the map value of the specified surface point is fixed
142  bool IsFixedPoint(int i) const;
143 
144  /// Get index of i-th point with free map value or -1 if map value of point is fixed
145  ///
146  /// \param[in] i Surface point index.
147  ///
148  /// \return Index of point in set of points with free map value.
149  int FreePointIndex(int i) const;
150 
151  /// Get surface point ID of i-th point with free map value
152  ///
153  /// \param[in] i Index of point in set of points with free map value.
154  ///
155  /// \return Surface point index.
156  int FreePointId(int i) const;
157 
158  /// Get index of i-th point with fixed map value or -1 if map value of point is free
159  ///
160  /// \param[in] i Surface point index.
161  ///
162  /// \return Index of point in set of points with fixed map value.
163  int FixedPointIndex(int i) const;
164 
165  /// Get surface point ID of i-th point with fixed map value
166  ///
167  /// \param[in] i Index of point in set of points with fixed map value.
168  ///
169  /// \return Surface point index.
170  int FixedPointId(int i) const;
171 
172  /// Get component of map value at surface vertex
173  ///
174  /// \param[in] i Surface point index.
175  /// \param[in] j Map value component index.
176  ///
177  /// \return The j-th component of the map value evaluated at the i-th surface point.
178  double GetValue(int i, int j = 0) const;
179 
180  /// Get component of map value at i-th free point
181  ///
182  /// \param[in] i Index of point in set of points with free map value.
183  /// \param[in] j Map value component index.
184  ///
185  /// \return The j-th component of the map value evaluated at the i-th free point.
186  double GetFreeValue(int i, int j = 0) const;
187 
188  /// Get component of map value at i-th fixed point
189  ///
190  /// \param[in] i Index of point in set of points with fixed map value.
191  /// \param[in] j Map value component index.
192  ///
193  /// \return The j-th component of the map value evaluated at the i-th fixed point.
194  double GetFixedValue(int i, int j = 0) const;
195 
196 protected:
197 
198  /// Set scalar map value at surface vertex
199  ///
200  /// \param[in] i Surface point index.
201  /// \param[in] v Map value.
202  void SetValue(int i, double v);
203 
204  /// Set component of map value at surface vertex
205  ///
206  /// \param[in] i Surface point index.
207  /// \param[in] j Map component index.
208  /// \param[in] v Map component value.
209  void SetValue(int i, int j, double v);
210 
211  /// Set scalar map value at i-th free point
212  ///
213  /// \param[in] i Index of point in set of points with free map value.
214  /// \param[in] v Map value.
215  void SetFreeValue(int i, double v);
216 
217  /// Set component of map value at i-th free point
218  ///
219  /// \param[in] i Index of point in set of points with free map value.
220  /// \param[in] j Map component index.
221  /// \param[in] v Map component value.
222  void SetFreeValue(int i, int j, double v);
223 
224 };
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 // Inline definitions
228 ////////////////////////////////////////////////////////////////////////////////
229 
230 // =============================================================================
231 // Auxiliaries
232 // =============================================================================
233 
234 // -----------------------------------------------------------------------------
236 {
237  return static_cast<int>(_FreePoints.size());
238 }
239 
240 // -----------------------------------------------------------------------------
242 {
243  return static_cast<int>(_FixedPoints.size());
244 }
245 
246 // -----------------------------------------------------------------------------
248 {
249  const int i = _PointIndex[ptId];
250  return (i < 0 ? -1 : i);
251 }
252 
253 // -----------------------------------------------------------------------------
255 {
256  return _FreePoints[i];
257 }
258 
259 // -----------------------------------------------------------------------------
261 {
262  return FreePointIndex(ptId) != -1;
263 }
264 
265 // -----------------------------------------------------------------------------
267 {
268  const int i = _PointIndex[ptId];
269  return (i < 0 ? (-i) - 1 : -1);
270 }
271 
272 // -----------------------------------------------------------------------------
274 {
275  return _FixedPoints[i];
276 }
277 
278 // -----------------------------------------------------------------------------
280 {
281  return FixedPointIndex(ptId) != -1;
282 }
283 
284 // -----------------------------------------------------------------------------
285 inline double SpectralConformalSurfaceMapper::GetValue(int i, int j) const
286 {
287  return _Values->GetComponent(static_cast<vtkIdType>(i), j);
288 }
289 
290 // -----------------------------------------------------------------------------
291 inline double SpectralConformalSurfaceMapper::GetFreeValue(int i, int j) const
292 {
293  return GetValue(FreePointId(i), j);
294 }
295 
296 // -----------------------------------------------------------------------------
297 inline double SpectralConformalSurfaceMapper::GetFixedValue(int i, int j) const
298 {
299  return GetValue(FixedPointId(i), j);
300 }
301 
302 // -----------------------------------------------------------------------------
303 inline void SpectralConformalSurfaceMapper::SetValue(int i, double v)
304 {
305  _Values->SetComponent(static_cast<vtkIdType>(i), 0, v);
306 }
307 
308 // -----------------------------------------------------------------------------
309 inline void SpectralConformalSurfaceMapper::SetValue(int i, int j, double v)
310 {
311  _Values->SetComponent(static_cast<vtkIdType>(i), j, v);
312 }
313 
314 // -----------------------------------------------------------------------------
316 {
317  SetValue(FreePointId(i), v);
318 }
319 
320 // -----------------------------------------------------------------------------
321 inline void SpectralConformalSurfaceMapper::SetFreeValue(int i, int j, double v)
322 {
323  SetValue(FreePointId(i), j, v);
324 }
325 
326 
327 } // namespace mirtk
328 
329 #endif // MIRTK_SpectralConformalSurfaceMapper_H
bool IsFreePoint(int i) const
Whether the map value of the specified surface point is free.
virtual void Initialize()
Initialize filter after input and parameters are set.
bool IsFixedPoint(int i) const
Whether the map value of the specified surface point is fixed.
void AddFixedPoint(int i, double u, double v)
virtual void ComputeMap()
Compute surface map.
SpectralConformalSurfaceMapper()
Default constructor.
Definition: IOConfig.h:41
int NumberOfFreePoints() const
Number of surface points with free map value.
int NumberOfFixedPoints() const
Number of surface points with fixed map value.
virtual double Weight(int i, int j) const
SpectralConformalSurfaceMapper & operator=(const SpectralConformalSurfaceMapper &)
Assignment operator.
virtual ~SpectralConformalSurfaceMapper()
Destructor.
virtual void Finalize()
Finalize filter execution.