BoundaryMapper.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_BoundaryMapper_H
21 #define MIRTK_BoundaryMapper_H
22 
23 #include "mirtk/Object.h"
24 
25 #include "mirtk/Matrix.h"
26 #include "mirtk/Memory.h"
27 #include "mirtk/SurfaceBoundary.h"
28 #include "mirtk/PiecewiseLinearMap.h"
29 
30 
31 namespace mirtk {
32 
33 
34 /**
35  * Base class of filters which assign map values to surface boundary points
36  *
37  * Filters of this type take a piecewice linear surface boundary segments
38  * extracted from a surface mesh as input and compute a map value for each point
39  * on the surface boundary. Such piecewise linear boundary map can be used as
40  * fixed boundary condition for a surface map.
41  *
42  * \sa SurfaceMapper
43  */
44 class BoundaryMapper : public Object
45 {
46  mirtkAbstractMacro(BoundaryMapper);
47 
48  // ---------------------------------------------------------------------------
49  // Attributes
50 
51  /// Extracted surface mesh boundary
52  mirtkPublicAttributeMacro(SharedPtr<SurfaceBoundary>, Boundary);
53 
54  /// Map values at boundary points
55  ///
56  /// Not all boundary points need to have a boundary map value assigned by the
57  /// subclass implementation. The map value at these points is Not-a-Number (NaN).
58  mirtkAttributeMacro(Matrix, Values);
59 
60  /// Piecewise linear boundary map
61  mirtkReadOnlyAttributeMacro(SharedPtr<PiecewiseLinearMap>, Output);
62 
63  /// Copy attributes of this class from another instance
64  void CopyAttributes(const BoundaryMapper &);
65 
66  // ---------------------------------------------------------------------------
67  // Construction/Destruction
68 
69 protected:
70 
71  /// Default constructor
73 
74  /// Copy constructor
76 
77  /// Assignment operator
79 
80 public:
81 
82  /// Destructor
83  virtual ~BoundaryMapper();
84 
85  /// Create new copy of this instance
86  virtual BoundaryMapper *NewCopy() const = 0;
87 
88  // ---------------------------------------------------------------------------
89  // Execution
90 
91  /// Compute boundary map values
92  virtual void Run();
93 
94  /// Number of map value components
95  virtual int NumberOfComponents() const;
96 
97  /// Whether a given boundary point has a mapped value
98  ///
99  /// \param[in] i Boundary point index.
100  ///
101  /// \returns Whether this mapper assigned a map value to the specified boundary point.
102  bool HasBoundaryValue(int i) const;
103 
104  /// Get map value at boundary point
105  ///
106  /// \param[in] i Boundary point index.
107  /// \param[in] j Index of map value component.
108  ///
109  /// \returns Map value component at surface boundary point.
110  double GetBoundaryValue(int i, int j = 0) const;
111 
112  /// Get map value at surface point
113  ///
114  /// \param[in] ptId Surface point index.
115  /// \param[in] j Index of map value component.
116  ///
117  /// \returns Map value component at surface point.
118  double GetSurfaceValue(int ptId, int j = 0) const;
119 
120 protected:
121 
122  /// Initialize filter after input and parameters are set
123  virtual void Initialize();
124 
125  /// Assign map values to boundary points of surface mesh
126  virtual void ComputeMap() = 0;
127 
128  /// Finalize boundary map
129  virtual void Finalize();
130 
131  /// Set map value at boundary point
132  ///
133  /// \param[in] i Boundary point index.
134  /// \param[in] v Value of j-th map component.
135  ///
136  /// \returns Map value component at surface point.
137  void SetBoundaryValue(int i, double v);
138 
139  /// Set map value at boundary point
140  ///
141  /// \param[in] i Boundary point index.
142  /// \param[in] j Index of map value component.
143  /// \param[in] v Value of j-th map component.
144  ///
145  /// \returns Map value component at surface point.
146  void SetBoundaryValue(int i, int j, double v);
147 
148 };
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 // Inline definitions
152 ////////////////////////////////////////////////////////////////////////////////
153 
154 // =============================================================================
155 // Boundary map
156 // =============================================================================
157 
158 // -----------------------------------------------------------------------------
159 inline bool BoundaryMapper::HasBoundaryValue(int i) const
160 {
161  const int dim = _Values.Rows();
162  const double *value = _Values.Col(i);
163  for (int j = 0; j < dim; ++j) {
164  if (IsNaN(value[j])) return false;
165  }
166  return true;
167 }
168 
169 // -----------------------------------------------------------------------------
170 inline void BoundaryMapper::SetBoundaryValue(int i, int j, double v)
171 {
172  _Values.Col(i)[j] = v;
173 }
174 
175 // -----------------------------------------------------------------------------
176 inline void BoundaryMapper::SetBoundaryValue(int i, double v)
177 {
178  SetBoundaryValue(i, 0, v);
179 }
180 
181 // -----------------------------------------------------------------------------
182 inline double BoundaryMapper::GetBoundaryValue(int i, int j) const
183 {
184  return (HasBoundaryValue(i) ? _Values.Col(i)[j] : .0);
185 }
186 
187 // -----------------------------------------------------------------------------
188 inline double BoundaryMapper::GetSurfaceValue(int ptId, int j) const
189 {
190  const int i = _Boundary->Find(ptId);
191  return (i < .0 ? .0 : GetBoundaryValue(i, j));
192 }
193 
194 
195 } // namespace mirtk
196 
197 #endif // MIRTK_BoundaryMapper_H
virtual void ComputeMap()=0
Assign map values to boundary points of surface mesh.
double GetSurfaceValue(int ptId, int j=0) const
virtual BoundaryMapper * NewCopy() const =0
Create new copy of this instance.
void SetBoundaryValue(int i, double v)
BoundaryMapper & operator=(const BoundaryMapper &)
Assignment operator.
MIRTKCU_API bool IsNaN(double x)
Check if floating point value is not a number (NaN)
Definition: Math.h:91
virtual ~BoundaryMapper()
Destructor.
virtual void Run()
Compute boundary map values.
double GetBoundaryValue(int i, int j=0) const
virtual void Initialize()
Initialize filter after input and parameters are set.
Definition: IOConfig.h:41
virtual int NumberOfComponents() const
Number of map value components.
BoundaryMapper()
Default constructor.
bool HasBoundaryValue(int i) const
virtual void Finalize()
Finalize boundary map.