-
Notifications
You must be signed in to change notification settings - Fork 21
/
vtkCurveGenerator.h
262 lines (219 loc) · 12.2 KB
/
vtkCurveGenerator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*==============================================================================
Program: 3D Slicer
Copyright (c) Kitware Inc.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file was originally developed by Thomas Vaughan, PerkLab, Queen's University.
==============================================================================*/
#ifndef __vtkCurveGenerator_h
#define __vtkCurveGenerator_h
// vtk includes
#include <vtkParametricFunction.h>
#include <vtkPointLocator.h>
#include <vtkPolyData.h>
#include <vtkPolyDataAlgorithm.h>
#include <vtkSetGet.h>
#include <vtkSmartPointer.h>
class vtkSlicerDijkstraGraphGeodesicPath;
class vtkDoubleArray;
class vtkPoints;
class vtkSpline;
// export
#include "vtkAddonExport.h"
/// Filter that generates curves between points of an input polydata
class VTK_ADDON_EXPORT vtkCurveGenerator : public vtkPolyDataAlgorithm
{
public:
vtkTypeMacro(vtkCurveGenerator, vtkPolyDataAlgorithm);
static vtkCurveGenerator* New();
void PrintSelf(ostream& os, vtkIndent indent) override;
/// This indicates whether the curve should loop back in on itself,
/// connecting the last point back to the first point (disabled by default).
vtkSetMacro(CurveIsClosed, bool);
vtkGetMacro(CurveIsClosed, bool);
vtkBooleanMacro(CurveIsClosed, bool);
//@{
/// These methods are deprecated and will be removed in the future.
/// Use SetCurveIsClosed, GetCurveIsClosed, CurveIsCloseOn, CurveIsCloseOff methods instead.
void SetCurveIsLoop(bool loop) { this->SetCurveIsClosed(loop); }
void CurveIsLoopOn() { this->SetCurveIsClosed(true); }
void CurveIsLoopOff() { this->SetCurveIsClosed(false); }
bool GetCurveIsLoop() { return this->GetCurveIsClosed(); }
//@}
/// Type of curve to generate
enum
{
CURVE_TYPE_LINEAR_SPLINE = 0, // Curve interpolates between input points with straight lines
CURVE_TYPE_CARDINAL_SPLINE, // Curve interpolates between input points smoothly
CURVE_TYPE_KOCHANEK_SPLINE, // Curve interpolates between input points smoothly, generalized
CURVE_TYPE_POLYNOMIAL, // Curve approximates the input points with a polynomial fit
CURVE_TYPE_SHORTEST_DISTANCE_ON_SURFACE, // Curve finds the closest path along a the edges of a surface mesh
CURVE_TYPE_LAST // Valid types go above this line
};
vtkGetMacro(CurveType, int);
vtkSetMacro(CurveType, int);
static const char* GetCurveTypeAsString(int id);
static int GetCurveTypeFromString(const char* name);
void SetCurveTypeToLinearSpline() { this->SetCurveType(CURVE_TYPE_LINEAR_SPLINE); }
void SetCurveTypeToCardinalSpline() { this->SetCurveType(CURVE_TYPE_CARDINAL_SPLINE); }
void SetCurveTypeToKochanekSpline() { this->SetCurveType(CURVE_TYPE_KOCHANEK_SPLINE); }
void SetCurveTypeToPolynomial() { this->SetCurveType(CURVE_TYPE_POLYNOMIAL); }
void SetCurveTypeToShortestDistanceOnSurface() { this->SetCurveType(CURVE_TYPE_SHORTEST_DISTANCE_ON_SURFACE); }
virtual bool IsInterpolatingCurve();
/// Sample an *interpolating* curve this many times per segment (pair of points in sequence). Range 1 and up. Default 5.
vtkSetMacro(NumberOfPointsPerInterpolatingSegment, int);
vtkGetMacro(NumberOfPointsPerInterpolatingSegment, int);
/// Bias of derivative toward previous point (negative value) or next point. Range -1 to 1. Default 0.
vtkGetMacro(KochanekBias, double);
vtkSetMacro(KochanekBias, double);
/// Make the curve sharper( negative value) or smoother (positive value). Range -1 to 1. Default 0.
vtkGetMacro(KochanekContinuity, double);
vtkSetMacro(KochanekContinuity, double);
/// How quickly the curve turns, higher values like tightening an elastic. Range -1 to 1. Default 0.
vtkGetMacro(KochanekTension, double);
vtkSetMacro(KochanekTension, double);
/// Make the ends of the curve 'straighter' by copying derivative of the nearest point. Default false.
vtkGetMacro(KochanekEndsCopyNearestDerivatives, bool);
vtkSetMacro(KochanekEndsCopyNearestDerivatives, bool);
/// Set the order of the polynomials for fitting. Range 1 to 9 (equation becomes unstable from 9 upward). Default 1.
vtkGetMacro(PolynomialOrder, int);
vtkSetMacro(PolynomialOrder, int);
// Wednesday May 9, 2018 TODO
// InputParameters is currently computed by this class depending on the
// value of PolynomialPointSortingMethod, and is only supported for polynomials.
// In the future this could be expanded to support splines, and to allow
// the user to specify their own parameters (make a SetInputParameters function)
// e.g. through functions below
// Set the parameter values (e.g. point distances) that the curve should be based on
//virtual void SetInputParameters( vtkDoubleArray* );
//virtual vtkDoubleArray* GetInputParameters();
/// Set the sorting method for points in a polynomial.
enum
{
SORTING_METHOD_INDEX = 0,
SORTING_METHOD_MINIMUM_SPANNING_TREE_POSITION,
SORTING_METHOD_LAST // valid types should be written above this line
};
vtkGetMacro(PolynomialPointSortingMethod, int);
vtkSetMacro(PolynomialPointSortingMethod, int);
static const char* GetPolynomialPointSortingMethodAsString(int id);
static int GetPolynomialPointSortingMethodFromString(const char* name);
void SetPolynomialPointSortingMethodToIndex() { this->SetPolynomialPointSortingMethod(vtkCurveGenerator::SORTING_METHOD_INDEX); }
void SetPolynomialPointSortingMethodToMinimumSpanningTreePosition()
{
this->SetPolynomialPointSortingMethod(vtkCurveGenerator::SORTING_METHOD_MINIMUM_SPANNING_TREE_POSITION);
}
/// Set the type of fit for polynomials
/// see corresponding entries in vtkParametricPolynomialApproximation.h for more information
enum
{
POLYNOMIAL_FIT_METHOD_GLOBAL_LEAST_SQUARES = 0,
POLYNOMIAL_FIT_METHOD_MOVING_LEAST_SQUARES,
POLYNOMIAL_FIT_METHOD_LAST // Valid types go above this line
};
vtkGetMacro(PolynomialFitMethod, double);
vtkSetMacro(PolynomialFitMethod, double);
static const char* GetPolynomialFitMethodAsString(int id);
static int GetPolynomialFitMethodFromString(const char* name);
void SetPolynomialFitMethodToGlobalLeastSquares() { this->SetPolynomialFitMethod(vtkCurveGenerator::POLYNOMIAL_FIT_METHOD_GLOBAL_LEAST_SQUARES); }
void SetPolynomialFitMethodToMovingLeastSquares() { this->SetPolynomialFitMethod(vtkCurveGenerator::POLYNOMIAL_FIT_METHOD_MOVING_LEAST_SQUARES); }
/// Set the sampling distance (in parameter space) for moving least squares sampling
vtkGetMacro(PolynomialSampleWidth, double);
vtkSetMacro(PolynomialSampleWidth, double);
/// Set the weight function for moving least squares polynomial fits
/// see corresponding entries in vtkParametricPolynomialApproximation.h for more information
enum
{
POLYNOMIAL_WEIGHT_FUNCTION_RECTANGULAR = 0,
POLYNOMIAL_WEIGHT_FUNCTION_TRIANGULAR,
POLYNOMIAL_WEIGHT_FUNCTION_COSINE,
POLYNOMIAL_WEIGHT_FUNCTION_GAUSSIAN,
POLYNOMIAL_WEIGHT_FUNCTION_LAST // Valid types go above this line
};
vtkGetMacro(PolynomialWeightFunction, double);
vtkSetMacro(PolynomialWeightFunction, double);
static const char* GetPolynomialWeightFunctionAsString(int id);
static int GetPolynomialWeightFunctionFromString(const char* name);
void SetPolynomialWeightFunctionToRectangular() { this->SetPolynomialWeightFunction(vtkCurveGenerator::POLYNOMIAL_WEIGHT_FUNCTION_RECTANGULAR); }
void SetPolynomialWeightFunctionToTriangular() { this->SetPolynomialWeightFunction(vtkCurveGenerator::POLYNOMIAL_WEIGHT_FUNCTION_TRIANGULAR); }
void SetPolynomialWeightFunctionToCosine() { this->SetPolynomialWeightFunction(vtkCurveGenerator::POLYNOMIAL_WEIGHT_FUNCTION_COSINE); }
void SetPolynomialWeightFunctionToGaussian() { this->SetPolynomialWeightFunction(vtkCurveGenerator::POLYNOMIAL_WEIGHT_FUNCTION_GAUSSIAN); }
/// If the surface scalars should be used to weight the distances in the pathfinding algorithm
int GetSurfaceCostFunctionType();
void SetSurfaceCostFunctionType(int surfaceCostFunctionType);
/// Get the control point id from the interpolated point id
/// Currently only works for shortest surface distance
vtkIdType GetControlPointIdFromInterpolatedPointId(vtkIdType interpolatedPointId);
/// Get the list of curve point ids on the surface mesh
vtkIdList* GetSurfacePointIds();
/// Get the length of the curve
double GetOutputCurveLength();
/// The internal instance of the current parametric function use of the curve for other computations.
vtkParametricFunction* GetParametricFunction() { return this->ParametricFunction.GetPointer(); };
/// Set the input control points
void SetInputPoints(vtkPoints* points);
/// Get the output sampled points
vtkPoints* GetOutputPoints();
/// Calculates point parameters for use in vtkParametricPolynomialApproximation
/// The parameter values are based on the point index and range from 0.0 at the start to 1.0 at the end of the line.
/// \sa SortByMinimumSpanningTreePosition
/// \param inputPoints Input list of points. The points form a continuous line from the first to last point.
/// \param outputParameters Parameters used by vtkParametricPolynomialApproximation to approximate a polynomial from the input points.
static void SortByIndex(vtkPoints* inputPoints, vtkDoubleArray* outputParameters);
/// Calculates point parameters for use in vtkParametricPolynomialApproximation
/// The parameter values are calculated using the following algorithm:
/// 1. Construct an undirected graph as a 2D array
/// 2. Find the two vertices that are the farthest apart
/// 3. Run prim's algorithm on the graph
/// 4. Extract the "trunk" path from the last vertex to the first
/// 5. Based on the distance along that path, assign each vertex a polynomial parameter value
/// \sa SortByIndex
/// \param inputPoints Input point cloud that should be sorted to form a continuous line.
/// \param outputParameters Parameters used by vtkParametricPolynomialApproximation to approximate a polynomial from the input points.
static void SortByMinimumSpanningTreePosition(vtkPoints* inputPoints, vtkDoubleArray* outputParameters);
protected:
// input parameters
int NumberOfPointsPerInterpolatingSegment;
int CurveType;
bool CurveIsClosed;
double KochanekBias;
double KochanekContinuity;
double KochanekTension;
bool KochanekEndsCopyNearestDerivatives;
int PolynomialOrder;
int PolynomialPointSortingMethod;
int PolynomialFitMethod;
double PolynomialSampleWidth;
int PolynomialWeightFunction;
std::vector<vtkIdType> InterpolatedPointIdsForControlPoints;
// internal storage
vtkSmartPointer<vtkPointLocator> SurfacePointLocator;
vtkSmartPointer<vtkSlicerDijkstraGraphGeodesicPath> SurfacePathFilter;
vtkSmartPointer<vtkDoubleArray> InputParameters;
vtkSmartPointer<vtkParametricFunction> ParametricFunction;
// output
double OutputCurveLength;
// logic
void SetParametricFunctionToSpline(vtkPoints* inputPoints, vtkSpline* xSpline, vtkSpline* ySpline, vtkSpline* zSpline);
void SetParametricFunctionToLinearSpline(vtkPoints* inputPoints);
void SetParametricFunctionToCardinalSpline(vtkPoints* inputPoints);
void SetParametricFunctionToKochanekSpline(vtkPoints* inputPoints);
void SetParametricFunctionToPolynomial(vtkPoints* inputPoints);
int GeneratePoints(vtkPoints* inputPoints, vtkPolyData* inputSurface, vtkPolyData* outputPolyData);
int GeneratePointsFromFunction(vtkPoints* inputPoints, vtkPoints* outputPoints, vtkDoubleArray* outputPedigreeIdArray);
int GeneratePointsFromSurface(vtkPoints* inputPoints, vtkPolyData* inputSurface, vtkPoints* outputPoints, vtkDoubleArray* outputPedigreeIdArray);
int GenerateLines(vtkPolyData* polyData);
int FillInputPortInformation(int port, vtkInformation* info) override;
int RequestData(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector) override;
protected:
vtkCurveGenerator();
~vtkCurveGenerator() override;
vtkCurveGenerator(const vtkCurveGenerator&) = delete;
void operator=(const vtkCurveGenerator&) = delete;
};
#endif