TTK
Loading...
Searching...
No Matches
ttkMetricDistortion.cpp
Go to the documentation of this file.
2
3#include <vtkInformation.h>
4
5#include <vtkCellData.h>
6#include <vtkDataArray.h>
7#include <vtkDataSet.h>
8#include <vtkDoubleArray.h>
9#include <vtkObjectFactory.h>
10#include <vtkPointData.h>
11#include <vtkPointSet.h>
12#include <vtkSmartPointer.h>
13#include <vtkTable.h>
14
15#include <ttkMacros.h>
16#include <ttkUtils.h>
17
18// A VTK macro that enables the instantiation of this class via ::New()
19// You do not have to modify this
21
35 this->SetNumberOfInputPorts(2);
36 this->SetNumberOfOutputPorts(1);
37}
38
40
49 vtkInformation *info) {
50 if(port == 0) {
51 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
52 } else if(port == 1) {
53 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
54 info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
55 } else
56 return 0;
57 return 1;
58}
59
76 vtkInformation *info) {
77 if(port == 0) {
79 return 1;
80 }
81 return 0;
82}
83
97template <class tableDataType>
98int ttkMetricDistortion::run(vtkInformationVector **inputVector) {
99 vtkPointSet *inputSurface = vtkPointSet::GetData(inputVector[0]);
100 auto triangulation = ttkAlgorithm::GetTriangulation(inputSurface);
101 if(!triangulation) {
102 printErr("Unable to load triangulation.");
103 return -4;
104 }
105 this->preconditionTriangulation(triangulation);
106
107 // Load Table
108 vtkTable *distanceMatrixVTK = vtkTable::GetData(inputVector[1]);
109 std::vector<tableDataType *> distanceMatrix;
110 if(distanceMatrixVTK) {
111 auto noRows = distanceMatrixVTK->GetNumberOfRows();
112 distanceMatrix = std::vector<tableDataType *>(noRows);
113 for(unsigned int i = 0; i < noRows; ++i) {
114 auto row = vtkDataArray::SafeDownCast(distanceMatrixVTK->GetColumn(i));
115 if(!row) {
116 printErr("Unable to load column " + std::to_string(i)
117 + " in the distance matrix.");
118 return -5;
119 }
120 distanceMatrix[i] = ttkUtils::GetPointer<tableDataType>(row);
121 }
122 }
123
124 // --------------------------------------------------------------------------
125 // Call base
126 // --------------------------------------------------------------------------
127 computeSurfaceArea(triangulation->getData(), distanceMatrix, surfaceArea_,
128 metricArea_, ratioArea_);
129
130 computeSurfaceDistance(triangulation->getData(), distanceMatrix,
131 surfaceDistance_, metricDistance_, ratioDistance_,
132 surfacePointDistance_, metricPointDistance_,
133 ratioPointDistance_);
134
135 computeSurfaceCurvature(triangulation->getData(), distanceMatrix,
136 surfaceCurvature_, metricCurvature_, diffCurvature_);
137
138 return 1;
139}
140
141int ttkMetricDistortion::RequestData(vtkInformation *ttkNotUsed(request),
142 vtkInformationVector **inputVector,
143 vtkInformationVector *outputVector) {
144
145 // --------------------------------------------------------------------------
146 // Get input object from input vector
147 // --------------------------------------------------------------------------
148 // Load Surface
149 vtkPointSet *inputSurface = vtkPointSet::GetData(inputVector[0]);
150 if(!inputSurface) {
151 printErr("Unable to load input surface.");
152 return 0;
153 }
154 auto noPoints = inputSurface->GetNumberOfPoints();
155 if(noPoints == 0) {
156 printErr("Input surface should not have 0 points.");
157 return -1;
158 }
159 auto noCells = inputSurface->GetNumberOfCells();
160
161 vtkTable *distanceMatrixVTK = vtkTable::GetData(inputVector[1]);
162 bool validDistanceMatrix
163 = (distanceMatrixVTK
164 and distanceMatrixVTK->GetNumberOfColumns() == noPoints);
165 if(distanceMatrixVTK and not validDistanceMatrix) {
166 printErr("Distance matrix should have the same number of rows/columns than "
167 "the surface's number of points.");
168 return -2;
169 }
170 if(distanceMatrixVTK
171 and distanceMatrixVTK->GetNumberOfColumns()
172 != distanceMatrixVTK->GetNumberOfRows()) {
173 printErr("Distance matrix should be square.");
174 return -3;
175 }
176 int tableDataType
177 = (validDistanceMatrix ? distanceMatrixVTK->GetColumn(0)->GetDataType()
178 : VTK_DOUBLE);
179
180 surfaceArea_.clear();
181 metricArea_.clear();
182 ratioArea_.clear();
183 surfaceDistance_.clear();
184 metricDistance_.clear();
185 ratioDistance_.clear();
186 surfacePointDistance_.clear();
187 metricPointDistance_.clear();
188 ratioPointDistance_.clear();
189 surfaceCurvature_.clear();
190 metricCurvature_.clear();
191 diffCurvature_.clear();
192 int res = 1;
193 switch(tableDataType) {
194 vtkTemplateMacro(res = this->run<VTK_TT>(inputVector));
195 }
196 if(res != 1)
197 return res;
198
199 // --------------------------------------------------------------------------
200 // Get output object
201 // --------------------------------------------------------------------------
202 // --- Point Data
203 auto outputSurface = vtkPointSet::GetData(outputVector, 0);
204 outputSurface->DeepCopy(inputSurface);
205
206 vtkNew<vtkDoubleArray> surfaceCurvature_Array{};
207 surfaceCurvature_Array->SetName("SurfaceCurvature");
208 surfaceCurvature_Array->SetNumberOfTuples(noPoints);
209 vtkNew<vtkDoubleArray> metricCurvature_Array{};
210 metricCurvature_Array->SetName("MetricCurvature");
211 metricCurvature_Array->SetNumberOfTuples(noPoints);
212 vtkNew<vtkDoubleArray> ratioCurvatureArray{};
213 ratioCurvatureArray->SetName("CurvatureDiff");
214 ratioCurvatureArray->SetNumberOfTuples(noPoints);
215
216 for(unsigned int i = 0; i < noPoints; ++i) {
217 surfaceCurvature_Array->SetTuple1(i, surfaceCurvature_[i]);
218 metricCurvature_Array->SetTuple1(i, metricCurvature_[i]);
219 ratioCurvatureArray->SetTuple1(i, diffCurvature_[i]);
220 }
221
222 outputSurface->GetPointData()->AddArray(surfaceCurvature_Array);
223 if(validDistanceMatrix) {
224 outputSurface->GetPointData()->AddArray(metricCurvature_Array);
225 outputSurface->GetPointData()->AddArray(ratioCurvatureArray);
226 }
227
228 for(unsigned int i = 0; i < 3; ++i) {
229 std::string type{(i == 0 ? "Min" : (i == 1) ? "Max" : "Avg")};
230 vtkNew<vtkDoubleArray> surfaceIDistanceArray{};
231 surfaceIDistanceArray->SetName((type + "SurfaceEdgeLength").c_str());
232 surfaceIDistanceArray->SetNumberOfTuples(noPoints);
233 vtkNew<vtkDoubleArray> metricIDistanceArray{};
234 metricIDistanceArray->SetName((type + "MetricEdgeLength").c_str());
235 metricIDistanceArray->SetNumberOfTuples(noPoints);
236 vtkNew<vtkDoubleArray> ratioIDistanceArray{};
237 ratioIDistanceArray->SetName((type + "EdgeLengthRatio").c_str());
238 ratioIDistanceArray->SetNumberOfTuples(noPoints);
239 for(unsigned int j = 0; j < noPoints; ++j) {
240 surfaceIDistanceArray->SetTuple1(j, surfacePointDistance_[j][i]);
241 metricIDistanceArray->SetTuple1(j, metricPointDistance_[j][i]);
242 ratioIDistanceArray->SetTuple1(j, ratioPointDistance_[j][i]);
243 }
244 outputSurface->GetPointData()->AddArray(surfaceIDistanceArray);
245 if(validDistanceMatrix) {
246 outputSurface->GetPointData()->AddArray(metricIDistanceArray);
247 outputSurface->GetPointData()->AddArray(ratioIDistanceArray);
248 }
249 }
250
251 // --- Cell Data
252 vtkNew<vtkDoubleArray> surfaceArea_Array{};
253 surfaceArea_Array->SetName("SurfaceArea");
254 surfaceArea_Array->SetNumberOfTuples(noCells);
255 vtkNew<vtkDoubleArray> metricArea_Array{};
256 metricArea_Array->SetName("MetricArea");
257 metricArea_Array->SetNumberOfTuples(noCells);
258 vtkNew<vtkDoubleArray> ratioArea_Array{};
259 ratioArea_Array->SetName("AreaRatio");
260 ratioArea_Array->SetNumberOfTuples(noCells);
261
262 vtkNew<vtkDoubleArray> surfaceDistance_Array{};
263 surfaceDistance_Array->SetName("SurfaceEdgeLength");
264 surfaceDistance_Array->SetNumberOfTuples(noCells);
265 vtkNew<vtkDoubleArray> metricDistance_Array{};
266 metricDistance_Array->SetName("MetricEdgeLength");
267 metricDistance_Array->SetNumberOfTuples(noCells);
268 vtkNew<vtkDoubleArray> ratioDistance_Array{};
269 ratioDistance_Array->SetName("EdgeLengthRatio");
270 ratioDistance_Array->SetNumberOfTuples(noCells);
271
272 bool distanceAllNan = true;
273 for(unsigned int i = 0; i < noCells; ++i) {
274 surfaceArea_Array->SetTuple1(i, surfaceArea_[i]);
275 metricArea_Array->SetTuple1(i, metricArea_[i]);
276 ratioArea_Array->SetTuple1(i, ratioArea_[i]);
277 surfaceDistance_Array->SetTuple1(i, surfaceDistance_[i]);
278 metricDistance_Array->SetTuple1(i, metricDistance_[i]);
279 ratioDistance_Array->SetTuple1(i, ratioDistance_[i]);
280 if(surfaceDistance_[i] == surfaceDistance_[i]) // detect NaN
281 distanceAllNan = false;
282 }
283
284 outputSurface->GetCellData()->AddArray(surfaceArea_Array);
285 if(validDistanceMatrix) {
286 outputSurface->GetCellData()->AddArray(metricArea_Array);
287 outputSurface->GetCellData()->AddArray(ratioArea_Array);
288 }
289 if(not distanceAllNan) {
290 outputSurface->GetCellData()->AddArray(surfaceDistance_Array);
291 if(validDistanceMatrix) {
292 outputSurface->GetCellData()->AddArray(metricDistance_Array);
293 outputSurface->GetCellData()->AddArray(ratioDistance_Array);
294 }
295 }
296
297 // return success
298 return 1;
299}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition: BaseClass.h:47
static vtkInformationIntegerKey * SAME_DATA_TYPE_AS_INPUT_PORT()
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
TTK VTK-filter that wraps the ttk::MetricDistortion module.
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int run(vtkInformationVector **inputVector)
~ttkMetricDistortion() override
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition: Debug.h:149
int preconditionTriangulation(AbstractTriangulation *triangulation)
void computeSurfaceArea(const triangulationType *triangulation, std::vector< tableDataType * > &distanceMatrix, std::vector< double > &surfaceArea, std::vector< double > &metricArea, std::vector< double > &ratioArea)
void computeSurfaceDistance(const triangulationType *triangulation, std::vector< tableDataType * > &distanceMatrix, std::vector< double > &surfaceDistance, std::vector< double > &metricDistance, std::vector< double > &ratioDistance, std::vector< std::array< double, 3 > > &surfacePointDistance, std::vector< std::array< double, 3 > > &metricPointDistance, std::vector< std::array< double, 3 > > &ratioPointDistance)
void computeSurfaceCurvature(const triangulationType *triangulation, std::vector< tableDataType * > &distanceMatrix, std::vector< double > &surfaceCurvature, std::vector< double > &metricCurvature, std::vector< double > &diffCurvature)
vtkStandardNewMacro(ttkMetricDistortion)