SurfaceCurvature.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_SurfaceCurvature_H
21 #define MIRTK_SurfaceCurvature_H
22 
23 #include "mirtk/SurfaceFilter.h"
24 #include "mirtk/PointSetExport.h"
25 
26 #include "vtkDataArray.h"
27 
28 
29 namespace mirtk {
30 
31 
32 /**
33  * Compute curvature at each point of a surface mesh
34  *
35  * This curvature computation is based on a robust estimation of the 3D curvature
36  * tensor field as implemented in Matlab by Gabriel Peyre:
37  *
38  * http://uk.mathworks.com/matlabcentral/fileexchange/5355-toolbox-graph/content/toolbox_graph/compute_curvature.m
39  *
40  * The algorithm is detailed in
41  * David Cohen-Steiner and Jean-Marie Morvan.
42  * Restricted Delaunay triangulations and normal cycle.
43  * In Proc. 19th Annual ACM Symposium on Computational Geometry,
44  * pages 237-246, 2003.
45  * and also in
46  * Pierre Alliez, David Cohen-Steiner, Olivier Devillers, Bruno LeŽvy, and Mathieu Desbrun.
47  * Anisotropic Polygonal Remeshing.
48  * ACM Transactions on Graphics, 2003.
49  * Note: SIGGRAPH '2003 Conference Proceedings
50  *
51  * Alternatively, the vtkCurvatures filter can be used to compute mean curvature,
52  * Gauss curvature, and minimum and maximum curvature. To enable the use of this
53  * VTK filter, call VtkCurvaturesOn(). This option is ignored when the curvature
54  * tensor or principle directions are requested. If multiple curvature types
55  * supported by vtkCurvatures are requested, the minimum and maximum curvatures
56  * are computed by this filter from the mean and Gauss curvature values obtained
57  * by vtkCurvatures, to avoid the duplicate computation of these curvature
58  * values when using the vtkCurvatures filter. This computation is identical to
59  * vtkCurvatures::GetMinimumCurvature and vtkCurvatures::GetMaximumCurvature.
60  */
62 {
63  mirtkObjectMacro(SurfaceCurvature);
64 
65  // ---------------------------------------------------------------------------
66  // Types
67 
68 public:
69 
70  /// Enumeration of output curvature measures, can be combined using bitwise OR
71  enum Type
72  {
73  Minimum = 1, ///< Minimum principal curvature, k_min
74  Maximum = 2, ///< Maximum principal curvature, k_max
75  Principal = 4, ///< Both principal curvatures in single array
76  Mean = 8, ///< Mean curvature, (k_min + k_max)/2
77  Gauss = 16, ///< Gauss curvature, k_min * k_max
78  Curvedness = 32, ///< Curvedness, i.e., sqrt((k_min^2 + k_max^2) / 2)
79  Normal = 64, ///< Point normal computed from curvature tensor
80  MinimumDirection = 128, ///< Direction of minimum curvature
81  MaximumDirection = 256, ///< Direction of maximum curvature
82  Tensor = 512, ///< 6 entries of symmetric 3x3 curvature tensor
83  InverseTensor = 1024, ///< 6 entries of inverse of symmetric 3x3 curvature tensor
84  Scalars = Minimum | Maximum | Mean | Gauss | Curvedness,
86  };
87 
88  /// Component indices of tensor output array
89  ///
90  /// This order is compatible with ParaView, which automatically labels the
91  /// entries in this order.
93  {
94  XX = 0, YY = 1, ZZ = 2, XY = 3, YX = XY, YZ = 4, ZY = YZ, XZ = 5, ZX = XZ
95  };
96 
97  // Names of data arrays
98  MIRTK_PointSet_EXPORT static const char * const MINIMUM; ///< Name of minimum curvature array
99  MIRTK_PointSet_EXPORT static const char * const MAXIMUM; ///< Name of maximum curvature array
100  MIRTK_PointSet_EXPORT static const char * const PRINCIPAL; ///< Name of principal curvatures array
101  MIRTK_PointSet_EXPORT static const char * const MEAN; ///< Name of mean curvature array
102  MIRTK_PointSet_EXPORT static const char * const GAUSS; ///< Name of Gauss curvature array
103  MIRTK_PointSet_EXPORT static const char * const CURVEDNESS; ///< Name of curvedness array
104  MIRTK_PointSet_EXPORT static const char * const NORMALS; ///< Name of curvature-based normals array
105  MIRTK_PointSet_EXPORT static const char * const MINIMUM_DIRECTION; ///< Name of minimum curvature direction array
106  MIRTK_PointSet_EXPORT static const char * const MAXIMUM_DIRECTION; ///< Name of maximum curvature direction array
107  MIRTK_PointSet_EXPORT static const char * const TENSOR; ///< Name of curvature tensor array
108  MIRTK_PointSet_EXPORT static const char * const INVERSE_TENSOR; ///< Name of inverse curvature tensor array
109 
110  // ---------------------------------------------------------------------------
111  // Attributes
112 
113 protected:
114 
115  /// Curvature type(s) to compute
116  mirtkPublicAttributeMacro(int, CurvatureType);
117 
118  /// Whether to use vtkCurvatures filter instead
119  mirtkPublicAttributeMacro(bool, VtkCurvatures);
120 
121  /// Number of tensor averaging iterations
122  mirtkPublicAttributeMacro(int, TensorAveraging);
123 
124  /// Whether to normalize curvature assuming a spherical shape
125  mirtkPublicAttributeMacro(bool, Normalize);
126 
127  /// Volume of convex hull
128  /// \note Compute only if NormalizeOn.
130 
131  /// Radius of sphere have the same volume as the convex hull
132  /// \note Compute only if NormalizeOn.
133  mirtkReadOnlyAttributeMacro(double, Radius);
134 
135  /// Copy attributes of this class from another instance
136  void CopyAttributes(const SurfaceCurvature &);
137 
138 public:
139 
140  // ---------------------------------------------------------------------------
141  // Construction/Destruction
142 
143  /// Default constructor
144  SurfaceCurvature(int type = Scalars);
145 
146  /// Copy constructor
148 
149  /// Assignment operator
151 
152  /// Destructor
153  virtual ~SurfaceCurvature();
154 
155  // ---------------------------------------------------------------------------
156  // Execution
157 
158  /// Initialize filter after input and parameters are set
159  virtual void Initialize();
160 
161  /// Get/compute minimum curvature
162  ///
163  /// If Run was executed and the minimum curvature was included in the
164  /// requested output curvature types, this function just returns the
165  /// respective point data array. Otherwise, Initialize must be called
166  /// first and this function will compute the mean, Gauss, and minimum
167  /// curvatures using the vtkCurvatures filter.
168  ///
169  /// \note Smoothing is not performed unless Run is executed.
170  vtkDataArray *GetMinimumCurvature();
171 
172  /// Get/compute maximum curvature
173  ///
174  /// If Run was executed and the maximum curvature was included in the
175  /// requested output curvature types, this function just returns the
176  /// respective point data array. Otherwise, Initialize must be called
177  /// first and this function will compute the mean, Gauss, and maximum
178  /// curvatures using the vtkCurvatures filter.
179  ///
180  /// \note Smoothing is not performed unless Run is executed.
181  vtkDataArray *GetMaximumCurvature();
182 
183  /// Get/compute principal curvatures
184  ///
185  /// If Run was executed and the principle curvatures were included in
186  /// the requested output curvature types, this function just returns
187  /// the respective point data array. Otherwise, Initialize must be called
188  /// first and this function will compute the mean, Gauss, and principle
189  /// curvatures using the vtkCurvatures filter.
190  ///
191  /// When the minimum and maximum curvatures were computed before and stored
192  /// in separate output point data arrays, this function only allocates a new
193  /// output point data array to store both principal curvatures.
194  ///
195  /// \note Smoothing is not performed unless Run is executed.
196  vtkDataArray *GetPrincipalCurvatures();
197 
198  /// Get/compute mean curvature
199  ///
200  /// If Run was executed and the mean curvature was included in the
201  /// requested output curvature types, this function just returns the
202  /// respective point data array. Otherwise, Initialize must be called
203  /// first and this function will compute the mean curvature only using
204  /// the vtkCurvatures filter.
205  ///
206  /// \note Smoothing is not performed unless Run is executed.
207  vtkDataArray *GetMeanCurvature();
208 
209  /// Get/compute Gauss curvature
210  ///
211  /// If Run was executed and the Gauss curvature was included in the
212  /// requested output curvature types, this function just returns the
213  /// respective point data array. Otherwise, Initialize must be called
214  /// first and this function will compute the Gauss curvature only using
215  /// the vtkCurvatures filter.
216  ///
217  /// \note Smoothing is not performed unless Run is executed.
218  vtkDataArray *GetGaussCurvature();
219 
220  /// Get/compute curvedness
221  ///
222  /// If Run was executed and the curvedness was included in the
223  /// requested output curvature types, this function just returns the
224  /// respective point data array. Otherwise, Initialize must be called
225  /// first and this function will compute the mean, Gauss, minimum, and
226  /// maximum curvature using the vtkCurvatures filter and then compute the
227  /// curvedness from the minimum and maximum curvature.
228  ///
229  /// \note Smoothing is not performed unless Run is executed.
230  vtkDataArray *GetCurvedness();
231 
232 protected:
233 
234  /// Execute filter
235  virtual void Execute();
236 
237  /// Compute curvature tensors
238  void ComputeTensorField();
239 
240  /// Compute eigenvalues (and eigenvectors) of curvature tensors
241  void DecomposeTensorField();
242 
243  /// Compute mean curvature
244  void ComputeMeanCurvature();
245 
246  /// Compute Gauss curvature
247  void ComputeGaussCurvature();
248 
249  /// Compute principal curvatures from mean and Gauss curvature
251 
252  /// Compute minimum and/or maximum curvature from mean and Gauss curvature
253  void ComputeMinMaxCurvature(bool, bool);
254 
255  /// Compute curvedness measure
256  void ComputeCurvedness();
257 
258  /// Finalize filter execution
259  virtual void Finalize();
260 
261  // ---------------------------------------------------------------------------
262  // Alternative VTK-like interface
263 
264 public:
265 
266  /// Set output curvature types
267  mirtkSetMacro(CurvatureType, int);
268 
269  /// Get output curvature types
270  mirtkGetMacro(CurvatureType, int);
271 
272  /// Enable/disable use of vtkCurvatures filter
273  mirtkOnOffMacro(VtkCurvatures);
274 
275  /// Enable/disable normalization of mean and Gauss curvature
276  mirtkOnOffMacro(Normalize);
277 
278  /// Set number of curvature tensor averaging iterations
279  mirtkSetMacro(TensorAveraging, int);
280 
281  /// Get number of curvature tensor averaging iterations
282  mirtkGetMacro(TensorAveraging, int);
283 
284 };
285 
286 
287 } // namespace mirtk
288 
289 #endif // MIRTK_SurfaceCurvature_H
static MIRTK_PointSet_EXPORT const char *const NORMALS
Name of curvature-based normals array.
mirtkGetMacro(CurvatureType, int)
Get output curvature types.
virtual void Finalize()
Finalize filter execution.
Gauss curvature, k_min * k_max.
SurfaceCurvature(int type=Scalars)
Default constructor.
void ComputeGaussCurvature()
Compute Gauss curvature.
static MIRTK_PointSet_EXPORT const char *const PRINCIPAL
Name of principal curvatures array.
Direction of maximum curvature.
vtkDataArray * GetGaussCurvature()
mirtkOnOffMacro(VtkCurvatures)
Enable/disable use of vtkCurvatures filter.
mirtkReadOnlyAttributeMacro(double, Volume)
mirtkSetMacro(CurvatureType, int)
Set output curvature types.
double Volume(vtkSmartPointer< vtkPolyData >)
Get approximate volume enclosed by polygonal mesh.
vtkDataArray * GetPrincipalCurvatures()
void DecomposeTensorField()
Compute eigenvalues (and eigenvectors) of curvature tensors.
void ComputeCurvedness()
Compute curvedness measure.
virtual void Initialize()
Initialize filter after input and parameters are set.
6 entries of inverse of symmetric 3x3 curvature tensor
Definition: IOConfig.h:41
virtual ~SurfaceCurvature()
Destructor.
Mean curvature, (k_min + k_max)/2.
Curvedness, i.e., sqrt((k_min^2 + k_max^2) / 2)
virtual void Execute()
Execute filter.
static MIRTK_PointSet_EXPORT const char *const GAUSS
Name of Gauss curvature array.
void CopyAttributes(const SurfaceCurvature &)
Copy attributes of this class from another instance.
static MIRTK_PointSet_EXPORT const char *const TENSOR
Name of curvature tensor array.
vtkDataArray * GetMinimumCurvature()
6 entries of symmetric 3x3 curvature tensor
void ComputeMinMaxCurvature(bool, bool)
Compute minimum and/or maximum curvature from mean and Gauss curvature.
mirtkPublicAttributeMacro(int, CurvatureType)
Curvature type(s) to compute.
Type
Enumeration of output curvature measures, can be combined using bitwise OR.
SurfaceCurvature & operator=(const SurfaceCurvature &)
Assignment operator.
static MIRTK_PointSet_EXPORT const char *const CURVEDNESS
Name of curvedness array.
static MIRTK_PointSet_EXPORT const char *const MEAN
Name of mean curvature array.
Minimum principal curvature, k_min.
Direction of minimum curvature.
static MIRTK_PointSet_EXPORT const char *const INVERSE_TENSOR
Name of inverse curvature tensor array.
vtkDataArray * GetCurvedness()
vtkDataArray * GetMaximumCurvature()
static MIRTK_PointSet_EXPORT const char *const MINIMUM
Name of minimum curvature array.
Maximum principal curvature, k_max.
void ComputeMeanCurvature()
Compute mean curvature.
Both principal curvatures in single array.
static MIRTK_PointSet_EXPORT const char *const MAXIMUM
Name of maximum curvature array.
void ComputeTensorField()
Compute curvature tensors.
static MIRTK_PointSet_EXPORT const char *const MINIMUM_DIRECTION
Name of minimum curvature direction array.
Point normal computed from curvature tensor.
static MIRTK_PointSet_EXPORT const char *const MAXIMUM_DIRECTION
Name of maximum curvature direction array.
vtkDataArray * GetMeanCurvature()
void ComputePrincipalCurvatures()
Compute principal curvatures from mean and Gauss curvature.