DeformableSurfaceModel.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_DeformableSurfaceModel_H
21 #define MIRTK_DeformableSurfaceModel_H
22 
23 #include "mirtk/ObjectiveFunction.h"
24 
25 #include "mirtk/Array.h"
26 
27 #include "mirtk/RegisteredImage.h"
28 #include "mirtk/RegisteredPointSet.h"
29 
30 #include "mirtk/EnergyTerm.h"
31 #include "mirtk/ExternalForce.h"
32 #include "mirtk/InternalForce.h"
33 #include "mirtk/TransformationConstraint.h"
34 #include "mirtk/MeshSmoothing.h"
35 
36 #include "vtkSmartPointer.h"
37 #include "vtkPointSet.h"
38 #include "vtkPolyData.h"
39 #include "vtkAbstractCellLocator.h"
40 
41 
42 namespace mirtk {
43 
44 
45 /**
46  * Energy function describing a deformable surface model
47  */
49 {
50  mirtkObjectMacro(DeformableSurfaceModel);
51 
52  // ---------------------------------------------------------------------------
53  // Attributes
54 
55  /// Input point set / surface mesh
56  mirtkPublicAttributeMacro(vtkSmartPointer<vtkPointSet>, Input);
57 
58  /// Intensity image
59  mirtkPublicAggregateMacro(RegisteredImage, Image);
60 
61  /// Implicit surface distance image
62  mirtkPublicAggregateMacro(RegisteredImage, ImplicitSurface);
63 
64  /// Transformation to deform the point set with (optional)
65  mirtkPublicAggregateMacro(class Transformation, Transformation);
66 
67  /// Deformed point set / surface mesh
68  mirtkReadOnlyAttributeMacro(RegisteredPointSet, PointSet);
69 
70  /// Number of energy terms
71  mirtkReadOnlyAttributeMacro(int, NumberOfTerms);
72 
73  /// Minimum/default radius of node neighborhood
74  mirtkPublicAttributeMacro(int, NeighborhoodRadius);
75 
76  /// Number of gradient averaging iterations
77  mirtkPublicAttributeMacro(int, GradientAveraging);
78 
79  /// Weighting function used for averaging of gradient vectors
80  mirtkPublicAttributeMacro(MeshSmoothing::WeightFunction, GradientWeighting);
81 
82  /// Whether to only average gradient vectors pointing in the same direction
83  /// as the unsmoothed gradient at the central node (i.e., positive dot product)
84  mirtkPublicAttributeMacro(bool, AverageSignedGradients);
85 
86  /// Whether to only average the magnitude of the gradient vectors
87  mirtkPublicAttributeMacro(bool, AverageGradientMagnitude);
88 
89  /// Minimum (average) output mesh edge length
90  mirtkPublicAttributeMacro(double, MinEdgeLength);
91 
92  /// Maximum (average) output mesh edge length
93  mirtkPublicAttributeMacro(double, MaxEdgeLength);
94 
95  /// Minimum edge end point normal angle of feature edges
96  mirtkPublicAttributeMacro(double, MinFeatureAngle);
97 
98  /// Maximum edge end point normal angle of feature edges
99  mirtkPublicAttributeMacro(double, MaxFeatureAngle);
100 
101  /// Whether inversion of triangles is allowed during local remeshing
102  mirtkPublicAttributeMacro(bool, AllowTriangleInversion);
103 
104  /// Remesh deformed surface every n-th iteration
105  mirtkPublicAttributeMacro(int, RemeshInterval);
106 
107  /// Number of iterations since last performed remeshing
108  mirtkAttributeMacro(int, RemeshCounter);
109 
110  /// Remesh surface using an adaptive edge length interval based on local curvature
111  mirtkPublicAttributeMacro(bool, RemeshAdaptively);
112 
113  /// Low-pass filter surface mesh every n-th iteration
114  mirtkPublicAttributeMacro(int, LowPassInterval);
115 
116  /// Number of low-pass filtering iterations
117  mirtkPublicAttributeMacro(int, LowPassIterations);
118 
119  /// Low-pass filter band
120  mirtkPublicAttributeMacro(double, LowPassBand);
121 
122  /// Maximum distance of deformed surface points from input surface
123  mirtkPublicAttributeMacro(double, MaxInputDistance);
124  vtkSmartPointer<vtkAbstractCellLocator> _InputCellLocator;
125 
126  /// Enforce non-self-intersection of deformed surface mesh
127  mirtkPublicAttributeMacro(bool, HardNonSelfIntersection);
128 
129  /// Minimum required distance between non-adjacent triangular faces
130  ///
131  /// This distance threshold applies when the center point of the other
132  /// face is in front of the current triangle whose collisions with other
133  /// triangles is being determined (cf. SurfaceCollisions::FrontfaceCollision).
134  mirtkPublicAttributeMacro(double, MinFrontfaceDistance);
135 
136  /// Minimum required distance between non-adjacent triangular faces
137  ///
138  /// This distance threshold applies when the center point of the other
139  /// face is at the backside of the current triangle whose collisions with other
140  /// triangles is being determined (cf. SurfaceCollisions::FrontfaceCollision).
141  mirtkPublicAttributeMacro(double, MinBackfaceDistance);
142 
143  /// Maximum angle between face normal and center to closest point vector
144  /// required for collision to be detected
145  mirtkPublicAttributeMacro(double, MaxCollisionAngle);
146 
147  /// Use fast approximate surface triangle collision test
148  mirtkPublicAttributeMacro(bool, FastCollisionTest);
149 
150  /// Disallow passive nodes from moving
151  mirtkPublicAttributeMacro(bool, FixPassivePoints);
152 
153  /// Allow nodes to move in outwards normal direction
154  mirtkPublicAttributeMacro(bool, AllowExpansion);
155 
156  /// Allow nodes to move in inwards normal direction
157  mirtkPublicAttributeMacro(bool, AllowContraction);
158 
159  /// Whether the deformable model is a surface mesh
160  mirtkReadOnlyAttributeMacro(bool, IsSurfaceMesh);
161 
162  /// Whether to only minimize the energy of external forces
163  mirtkPublicAttributeMacro(bool, MinimizeExtrinsicEnergy);
164 
165 protected:
166 
167  /// Number of iterations since last low-pass filtering
168  mutable int _LowPassCounter;
169 
170  /// Energy terms corresponding to external forces
171  Array<class ExternalForce *> _ExternalForce;
172  Array<bool> _ExternalForceOwner;
173 
174  /// Energy terms corresponding to internal forces
175  Array<class InternalForce *> _InternalForce;
176  Array<bool> _InternalForceOwner;
177 
178  /// Energy terms which regularize the parametric transformation
179  Array<TransformationConstraint *> _Constraint;
180  Array<bool> _ConstraintOwner;
181 
182  /// Input surface meshes which the deformed surface mesh may not intersect
183  Array<vtkSmartPointer<vtkPolyData> > _BoundaryConstraint;
184 
185 public:
186 
187  /// Output surface mesh
188  vtkSmartPointer<vtkPointSet> Output() const;
189 
190  // ---------------------------------------------------------------------------
191  // Construction/Destruction
192 private:
193 
194  /// Copy constructor
195  /// \note Intentionally not implemented!
197 
198  /// Assignment operator
199  /// \note Intentionally not implemented!
200  DeformableSurfaceModel &operator =(const DeformableSurfaceModel &);
201 
202 public:
203 
204  /// Constructor
206 
207  /// Destructor
208  virtual ~DeformableSurfaceModel();
209 
210  // ---------------------------------------------------------------------------
211  // Energy terms
212 
213  /// Initialize energy terms once input and parameters have been set
214  virtual void Initialize();
215 
216  /// Delete previously added energy terms
217  void Clear();
218 
219  /// Whether energy function has no terms
220  bool Empty() const;
221 
222  /// Number of energy terms
223  int NumberOfForces() const;
224 
225  /// Number of internal force terms
226  int NumberOfInternalForces() const;
227 
228  /// Number of external force terms
229  int NumberOfExternalForces() const;
230 
231  /// Add external force term and take over ownership of the object
232  void Add(class ExternalForce *, bool = true);
233 
234  /// Remove external force term and revoke ownership of the object
235  void Sub(class ExternalForce *);
236 
237  /// Add internal force term and take over ownership of the object
238  void Add(class InternalForce *, bool = true);
239 
240  /// Remove internal force term and revoke ownership of the object
241  void Sub(class InternalForce *);
242 
243  /// Add transformation regularization term and take over ownership of the object
244  void Add(TransformationConstraint *, bool = true);
245 
246  /// Remove transformation regularization term and revoke ownership of the object
248 
249  /// Get the n-th energy term
250  EnergyTerm *Term(int);
251 
252  /// Get the n-th energy term
253  const EnergyTerm *Term(int) const;
254 
255  /// Get the n-th external force term
256  class ExternalForce *ExternalForce(int);
257 
258  /// Get the n-th external force term
259  const class ExternalForce *ExternalForce(int) const;
260 
261  /// Get the n-th internal force term
262  class InternalForce *InternalForce(int);
263 
264  /// Get the n-th internal force term
265  const class InternalForce *InternalForce(int) const;
266 
267  /// Determine whether a given force term is an external force
268  static bool IsExternalForce(const EnergyTerm *);
269 
270  /// Determine whether a given force term is an external implicit surface force
271  static bool IsImplicitSurfaceForce(const EnergyTerm *);
272 
273  /// Determine whether a given force term is an internal force
274  static bool IsInternalForce(const EnergyTerm *);
275 
276  /// Determine whether n-th energy term is an external force
277  bool IsExternalForce(int) const;
278 
279  /// Determine whether n-th energy term is an external implicit surface force
280  bool IsImplicitSurfaceForce(int) const;
281 
282  /// Determine whether n-th energy term is an internal force
283  bool IsInternalForce(int) const;
284 
285  // ---------------------------------------------------------------------------
286  // Settings
287 
288  // Import other overloads
290 
291  /// Set parameter value from string
292  virtual bool Set(const char *, const char *);
293 
294  /// Get parameter as key/value as string map
295  virtual ParameterList Parameter() const;
296 
297  // ---------------------------------------------------------------------------
298  // Function parameters
299 
300  /// Get number of deformable surface parameters
301  virtual int NumberOfDOFs() const;
302 
303  /// Get number of deformable surface points
304  int NumberOfPoints() const;
305 
306  /// Set deformable surface parameters
307  ///
308  /// This function can be used to restore the deformable surface parameters
309  /// after a failed update which did not result in the desired improvement.
310  ///
311  /// \param[in] x Value of deformable surface parameters (DoFs).
312  virtual void Put(const double *x);
313 
314  /// Get deformable surface parameters
315  ///
316  /// This function can be used to store a backup of the current deformable
317  /// surface parameters before an update such that these can be restored using
318  /// the Put member function if the update did not result in the desired change
319  /// of the overall energy.
320  ///
321  /// \param[in] x Current values of deformable surface parameters (DoFs).
322  virtual void Get(double *x) const;
323 
324  /// Get function parameter value
325  ///
326  /// \returns Value of specified function parameter (DoF).
327  virtual double Get(int) const;
328 
329  /// Add change (i.e., scaled gradient) to each deformable surface parameter
330  ///
331  /// This function updates each parameter of the deformable surface model
332  /// given a vector of desired changes, i.e., the computed gradient of the
333  /// energy function.
334  ///
335  /// \param[in,out] dx Change of each function parameter (DoF) as computed by the
336  /// Gradient member function and scaled by a chosen step length.
337  /// The change of a parameter may be modified by this function
338  /// in order to satisfy the hard constraints (if any).
339  ///
340  /// \returns Maximum change of transformation parameter.
341  virtual double Step(double *dx);
342 
343  /// Update internal state after change of parameters
344  virtual void Update(bool = true);
345 
346  /// Update energy function after convergence
347  ///
348  /// For example, fiducial registration error (FRE) terms may update the
349  /// point correspondences before another gradient-based optimization of
350  /// the new FRE term.
351  ///
352  /// \returns Whether the energy function has changed.
353  virtual bool Upgrade();
354 
355  /// Perform local adaptive remeshing
356  ///
357  /// \returns Whether the surface model has been remeshed. The Update function
358  /// must be called after such remeshing operation before evaluating
359  /// the energy and/or gradient of the deformable surface model.
360  virtual bool Remesh();
361 
362  // ---------------------------------------------------------------------------
363  // Evaluation
364 
365  /// Query/evaluate initial value of energy function
366  double InitialValue();
367 
368  /// Get initial value of n-th energy term
369  double InitialValue(int);
370 
371  /// Evaluate energy function
372  double Value();
373 
374  /// Get value of n-th energy term computed upon last evaluation
375  double Value(int);
376 
377  /// Evaluate gradient of energy function
378  ///
379  /// This gradient corresponds to the weighted sum of external and internal
380  /// forces of the deformable surface model.
381  ///
382  /// \param[in] dx Gradient of energy function.
383  /// \param[in] step Step length for finite differences.
384  /// \param[out] sgn_chg Whether function parameter value is allowed to
385  /// change sign when stepping along the computed gradient.
386  void Gradient(double *dx, double step = .0, bool *sgn_chg = NULL);
387 
388  /// Compute norm of gradient of energy function
389  ///
390  /// This norm can, for example, be the maximum absolute parameter change,
391  /// the maximum control point displacement if a FFD transformation is used
392  /// to deform the initial surface mesh, or the maximum vertex displacement.
393  double GradientNorm(const double *) const;
394 
395  /// Adjust step length range
396  ///
397  /// \param[in] dx Gradient of objective function.
398  /// \param[inout] min Minimum step length.
399  /// \param[inout] max Maximum step length.
400  void GradientStep(const double *dx, double &min, double &max) const;
401 
402  /// Evaluate energy function
403  ///
404  /// This function first updates the internal state of the function object
405  /// if required due to a previous change of the function parameters and then
406  /// evaluates the current energy function value.
407  ///
408  /// \param[in] step Step length for finite differences.
409  /// \param[out] dx Gradient of objective function.
410  /// If \c NULL, only the function value is computed.
411  /// \param[out] sgn_chg Whether function parameter value is allowed to
412  /// change sign when stepping along the computed gradient.
413  /// Ignord if \p dx is \c NULL.
414  virtual double Evaluate(double *dx = NULL, double step = .0, bool *sgn_chg = NULL);
415 
416 protected:
417 
418  /// Smooth gradient such that neighboring points move coherently
419  virtual void SmoothGradient(double *dx) const;
420 
421  /// Adjust node displacements to avoid self-intersections and collisions
422  ///
423  /// \param[in,out] dx (Scaled) gradient of objective function.
424  /// \param[in] nsi Enforce non-self-intersection.
425  /// \param[in] mind Minimum front-facing distance.
426  /// \param[in] minw Minimum back-facing distance.
427  void ResolveSurfaceCollisions(double *dx, bool nsi, double mind, double minw) const;
428 
429  /// Enforce hard constraints on surface model deformation
430  ///
431  /// This function clamps a nodes' displacement vector (velocity times \f$\delta t\f$),
432  /// if otherwise the hard constraints of the deformable surface model would
433  /// be violated. Common hard constraints are non-self-intersection and a
434  /// maximum total node displacement. If the surface model is deformed by
435  /// a parametric transformation, this function does nothing as hard constraints
436  /// can only be enforced during the optimization when the parameters of the
437  /// deformable surface model are the positions of the individual surface nodes.
438  ///
439  /// \param[inout] dx (Scaled) gradient of objective function.
440  virtual void EnforceHardConstraints(double *dx) const;
441 
442  // ---------------------------------------------------------------------------
443  // Debugging
444 public:
445 
446  /// Get unweighted and unnormalized value of n-th energy term
447  /// \remarks Use for progress reporting only.
448  double RawValue(int);
449 
450  /// Write input of data force terms
451  virtual void WriteDataSets(const char *, const char *, bool = true) const;
452 
453  /// Write gradient of force terms
454  virtual void WriteGradient(const char *, const char *) const;
455 
456 };
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 // Inline definitions
460 ////////////////////////////////////////////////////////////////////////////////
461 
462 // -----------------------------------------------------------------------------
463 inline vtkSmartPointer<vtkPointSet> DeformableSurfaceModel::Output() const
464 {
465  return _PointSet.PointSet();
466 }
467 
468 // -----------------------------------------------------------------------------
470 {
471  return _PointSet.NumberOfPoints();
472 }
473 
474 
475 } // namespace mirtk
476 
477 #endif // MIRTK_DeformableSurfaceModel_H
double MinEdgeLength(vtkSmartPointer< vtkPoints > points, const EdgeTable &edgeTable)
void Clear()
Delete previously added energy terms.
class ExternalForce * ExternalForce(int)
Get the n-th external force term.
virtual void WriteDataSets(const char *, const char *, bool=true) const
Write input of data force terms.
virtual ~DeformableSurfaceModel()
Destructor.
int NumberOfForces() const
Number of energy terms.
DeformableSurfaceModel()
Constructor.
bool Empty() const
Whether energy function has no terms.
vtkSmartPointer< vtkPointSet > Output() const
Output surface mesh.
virtual ParameterList Parameter() const
Get parameter as key/value as string map.
int NumberOfPoints() const
Get number of deformable surface points.
Array< vtkSmartPointer< vtkPolyData > > _BoundaryConstraint
Input surface meshes which the deformed surface mesh may not intersect.
Array< Pair< string, string > > ParameterList
Ordered list of parameter name/value pairs.
Definition: Object.h:38
virtual int NumberOfDOFs() const
Get number of deformable surface parameters.
virtual void Put(const double *x)
virtual void WriteGradient(const char *, const char *) const
Write gradient of force terms.
Definition: IOConfig.h:41
static bool IsExternalForce(const EnergyTerm *)
Determine whether a given force term is an external force.
int NumberOfInternalForces() const
Number of internal force terms.
Array< class InternalForce * > _InternalForce
Energy terms corresponding to internal forces.
virtual bool Set(const char *, const char *)
Set parameter value from string.
virtual void Initialize()
Initialize energy terms once input and parameters have been set.
void GradientStep(const double *dx, double &min, double &max) const
Array< class ExternalForce * > _ExternalForce
Energy terms corresponding to external forces.
void ResolveSurfaceCollisions(double *dx, bool nsi, double mind, double minw) const
void Gradient(double *dx, double step=.0, bool *sgn_chg=NULL)
static bool IsImplicitSurfaceForce(const EnergyTerm *)
Determine whether a given force term is an external implicit surface force.
double MaxEdgeLength(vtkSmartPointer< vtkPoints > points, const EdgeTable &edgeTable)
void Sub(class ExternalForce *)
Remove external force term and revoke ownership of the object.
int NumberOfExternalForces() const
Number of external force terms.
WeightFunction
Enumeration of smoothing kernel functions.
Definition: MeshSmoothing.h:46
virtual ParameterList Parameter() const
Get parameter name/value pairs.
Definition: Object.h:139
EnergyTerm * Term(int)
Get the n-th energy term.
double InitialValue()
Query/evaluate initial value of energy function.
int _LowPassCounter
Number of iterations since last low-pass filtering.
double Value()
Evaluate energy function.
virtual void Update(bool=true)
Update internal state after change of parameters.
double GradientNorm(const double *) const
void Add(class ExternalForce *, bool=true)
Add external force term and take over ownership of the object.
virtual double Evaluate(double *dx=NULL, double step=.0, bool *sgn_chg=NULL)
class InternalForce * InternalForce(int)
Get the n-th internal force term.
bool IsSurfaceMesh(vtkDataSet *)
Determine whether a point set is a surface mesh.
virtual double Step(double *dx)
static bool IsInternalForce(const EnergyTerm *)
Determine whether a given force term is an internal force.
virtual void EnforceHardConstraints(double *dx) const
virtual void Get(double *x) const
virtual void SmoothGradient(double *dx) const
Smooth gradient such that neighboring points move coherently.
Array< TransformationConstraint * > _Constraint
Energy terms which regularize the parametric transformation.