ImplicitSurfaceForce.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_ImplicitSurfaceForce_H
21 #define MIRTK_ImplicitSurfaceForce_H
22 
23 #include "mirtk/SurfaceForce.h"
24 
25 #include "mirtk/LinearInterpolateImageFunction.h"
26 #include "mirtk/FastLinearImageGradientFunction.h"
27 
28 class vtkDataArray;
29 
30 
31 namespace mirtk {
32 
33 
34 /**
35  * Base class of external forces based on a target implicit surface
36  *
37  * The input _Image of these force terms is the discrete distance function of
38  * the implicit surface, e.g., a signed Euclidean distance transform of a binary
39  * object mask.
40  */
42 {
43  mirtkAbstractMacro(ImplicitSurfaceForce);
44 
45  // ---------------------------------------------------------------------------
46  // Types
47 public:
48 
51 
52  /// Enumeration of implicit surface distance measures
54  {
55  DM_Unknown,
56  DM_Minimum, ///< Minimum implicit surface distance
57  DM_Normal ///< Implicit surface distance in normal direction
58  };
59 
60  // ---------------------------------------------------------------------------
61  // Attributes
62 private:
63 
64  /// Type of implicit surface distance
65  mirtkPublicAttributeMacro(DistanceMeasureType, DistanceMeasure);
66 
67  /// Signed distance offset
68  mirtkPublicAttributeMacro(double, Offset);
69 
70  /// Minimum length of step when casting ray in normal direction
71  mirtkPublicAttributeMacro(double, MinStepLength);
72 
73  /// Maximum implicit surface distance considered for ray casting
74  mirtkPublicAttributeMacro(double, MaxDistance);
75 
76  /// Tolerance for implicit surface distance evaluation
77  mirtkPublicAttributeMacro(double, Tolerance);
78 
79  /// Number of (normal) distance smoothing iterations
80  ///
81  /// \note Used only when DistanceMeasure is DM_Normal.
82  mirtkPublicAttributeMacro(int, DistanceSmoothing);
83 
84  /// Whether to use heuristic to detect "holes" in implicit surface based on
85  /// the normal distances and to fill in these distances by average distances
86  /// of "hole" boundary points.
87  ///
88  /// \note Used only when DistanceMeasure is DM_Normal.
89  mirtkPublicAttributeMacro(bool, FillInHoles);
90 
91  /// Continuous implicit surface distance function
92  ImageFunction _Distance;
93 
94  /// Continuous implicit surface distance function gradient
95  ImageGradient _DistanceGradient;
96 
97  /// Copy attributes of this class from another instance
98  void CopyAttributes(const ImplicitSurfaceForce &);
99 
100  // ---------------------------------------------------------------------------
101  // Construction/Destruction
102 protected:
103 
104  /// Constructor
105  ImplicitSurfaceForce(const char * = "", double = 1.0);
106 
107  /// Copy constructor
109 
110  /// Assignment operator
112 
113 public:
114 
115  /// Destructor
116  virtual ~ImplicitSurfaceForce();
117 
118  /// Initialize force term once input and parameters have been set
119  virtual void Initialize();
120 
121  // ---------------------------------------------------------------------------
122  // Configuration
123 protected:
124 
125  /// Set parameter value from string
126  virtual bool SetWithPrefix(const char *, const char *);
127 
128  /// Set parameter value from string
129  virtual bool SetWithoutPrefix(const char *, const char *);
130 
131 public:
132 
133  // Import other overloads
135 
136  /// Get parameter name/value pairs
137  virtual ParameterList Parameter() const;
138 
139  // ---------------------------------------------------------------------------
140  // Surface distance
141 
142  /// Get self-distance value at given world position along specified direction
143  double SelfDistance(const double p[3], const double n[3]) const;
144 
145  /// Get distance value at given world position
146  ///
147  /// \param[in] p Point at which to evaluate implicit surface distance function.
148  ///
149  /// \returns Interpolated implicit surface distance function value.
150  double Distance(const double p[3]) const;
151 
152  /// Get distance value at given world position along specified direction
153  ///
154  /// \param[in] p Starting point for ray casting.
155  /// \param[in] n Direction of ray (incl. opposite direction).
156  ///
157  /// \returns Distance of closest intersection of ray cast from point \p p in
158  /// direction \p n (opposite directions) of length \c _MaxDistance.
159  /// If no intersection occurs, \c _MaxDistance is returned.
160  double Distance(const double p[3], const double n[3]) const;
161 
162  /// Get (normalized) distance gradient at given world position
163  ///
164  /// \param[in] p Point at which to evaluate implicit surface distance gradient.
165  /// \param[out] g Gradient of implicit surface distance.
166  /// \param[in] normalize Whether to normalize the gradient vector.
167  void DistanceGradient(const double p[3], double g[3], bool normalize = false) const;
168 
169 protected:
170 
171  /// Get pointer to point data array of minimum implicit surface distances
172  vtkDataArray *MinimumDistances() const;
173 
174  /// Initialize point data array used to store minimum implicit surface distances
176 
177  /// Update minimum distances to implicit surface
178  void UpdateMinimumDistances();
179 
180  /// Get pointer to point data array of implicit surface distances in normal directions
181  vtkDataArray *NormalDistances() const;
182 
183  /// Initialize point data array used to store implicit surface distances in normal directions
185 
186  /// Update distances from implicit surface in normal direction
187  void UpdateNormalDistances();
188 
189  /// Get pointer to point data array of implicit surface distances
190  vtkDataArray *Distances() const;
191 
192  /// Initialize point data array used to store implicit surface distances
193  void InitializeDistances();
194 
195  /// Update implicit surface distance measures
196  void UpdateDistances();
197 
198 };
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 // ImplicitSurfaceForce::Measure from/to string conversion
202 ////////////////////////////////////////////////////////////////////////////////
203 
204 // -----------------------------------------------------------------------------
205 /// Convert implicit surface distance measure enumeration value to string
206 template <>
207 inline string ToString(const enum ImplicitSurfaceForce::DistanceMeasureType &value,
208  int w, char c, bool left)
209 {
210  const char *str;
211  switch (value) {
212  case ImplicitSurfaceForce::DM_Minimum: str = "Minimum"; break;
213  case ImplicitSurfaceForce::DM_Normal: str = "Normal"; break;
214  default: str = "Unknown"; break;
215  }
216  return ToString(str, w, c, left);
217 }
218 
219 // -----------------------------------------------------------------------------
220 /// Convert string to implicit surface distance measure enumeration value
221 template <>
222 inline bool FromString(const char *str, enum ImplicitSurfaceForce::DistanceMeasureType &value)
223 {
224  string lstr = ToLower(str);
225  if (lstr == "minimum") value = ImplicitSurfaceForce::DM_Minimum;
226  else if (lstr == "normal") value = ImplicitSurfaceForce::DM_Normal;
227  else value = ImplicitSurfaceForce::DM_Unknown;
228  return (value != ImplicitSurfaceForce::DM_Unknown);
229 }
230 
231 
232 } // namespace mirtk
233 
234 #endif // MIRTK_ImplicitSurfaceForce_H
void DistanceGradient(const double p[3], double g[3], bool normalize=false) const
Implicit surface distance in normal direction.
void InitializeNormalDistances()
Initialize point data array used to store implicit surface distances in normal directions.
virtual bool SetWithoutPrefix(const char *, const char *)
Set parameter value from string.
Minimum implicit surface distance.
virtual ~ImplicitSurfaceForce()
Destructor.
ImplicitSurfaceForce & operator=(const ImplicitSurfaceForce &)
Assignment operator.
vtkDataArray * NormalDistances() const
Get pointer to point data array of implicit surface distances in normal directions.
virtual void Initialize()
Initialize force term once input and parameters have been set.
double Distance(const double p[3]) const
DistanceMeasureType
Enumeration of implicit surface distance measures.
Array< Pair< string, string > > ParameterList
Ordered list of parameter name/value pairs.
Definition: Object.h:38
void UpdateDistances()
Update implicit surface distance measures.
virtual ParameterList Parameter() const
Get parameter name/value pairs.
void InitializeMinimumDistances()
Initialize point data array used to store minimum implicit surface distances.
double SelfDistance(const double p[3], const double n[3]) const
Get self-distance value at given world position along specified direction.
virtual ParameterList Parameter() const
Get parameter key/value as string map.
string ToLower(const string &)
Convert string to lowercase letters.
Definition: IOConfig.h:41
virtual bool SetWithPrefix(const char *, const char *)
Set parameter value from string.
vtkDataArray * Distances() const
Get pointer to point data array of implicit surface distances.
void UpdateMinimumDistances()
Update minimum distances to implicit surface.
string ToString(const EnergyMeasure &value, int w, char c, bool left)
Convert energy measure enumeration value to string.
bool FromString(const char *str, EnergyMeasure &value)
Convert energy measure string to enumeration value.
vtkDataArray * MinimumDistances() const
Get pointer to point data array of minimum implicit surface distances.
void UpdateNormalDistances()
Update distances from implicit surface in normal direction.
void InitializeDistances()
Initialize point data array used to store implicit surface distances.
ImplicitSurfaceForce(const char *="", double=1.0)
Constructor.