TTK
Loading...
Searching...
No Matches
MetricDistortion.h
Go to the documentation of this file.
1
11
12#pragma once
13
14// ttk common includes
15#include <Debug.h>
16#include <Geometry.h>
17#include <Triangulation.h>
18
19namespace ttk {
20
27 class MetricDistortion : virtual public Debug {
28
29 public:
31
33 // Pre-condition functions.
34 if(triangulation) {
35 triangulation->preconditionBoundaryVertices();
36 triangulation->preconditionVertexNeighbors();
37 }
38 return 0;
39 }
40
41 template <class triangulationType, class tableDataType>
42 void computeSurfaceCurvature(const triangulationType *triangulation,
43 std::vector<tableDataType *> &distanceMatrix,
44 std::vector<double> &surfaceCurvature,
45 std::vector<double> &metricCurvature,
46 std::vector<double> &diffCurvature) {
47 unsigned int const dim = triangulation->getNumberOfVertices();
48 surfaceCurvature = std::vector<double>(dim, std::nan(""));
49 metricCurvature = std::vector<double>(dim, std::nan(""));
50 diffCurvature = std::vector<double>(dim, std::nan(""));
51
52 std::vector<std::vector<std::tuple<int, int>>> point2CellPoints(dim);
53 unsigned int noTriangle = 0, noQuad = 0;
54 for(int i = 0; i < triangulation->getNumberOfCells(); ++i) {
55 auto cellNoPoints = triangulation->getCellVertexNumber(i);
56 if(cellNoPoints < 3 or cellNoPoints > 4)
57 continue;
58 for(int j = 0; j < cellNoPoints; ++j) {
59 auto first = (j + 1) % cellNoPoints;
60 auto second = (j + (cellNoPoints - 1)) % cellNoPoints;
61
62 SimplexId i0, i1;
63 triangulation->getCellVertex(i, first, i0);
64 triangulation->getCellVertex(i, second, i1);
65
66 std::tuple<int, int> const tup = std::make_tuple(i0, i1);
67
68 SimplexId ij;
69 triangulation->getCellVertex(i, j, ij);
70 point2CellPoints[ij].push_back(tup);
71 }
72 noTriangle += (cellNoPoints == 3);
73 noQuad += (cellNoPoints == 4);
74 }
75
76#ifdef TTK_ENABLE_OPENMP
77#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_)
78#endif
79 for(unsigned int i = 0; i < dim; ++i) {
80 double sumAngleSurface = 0.0, sumAngleMetric = 0.0;
81
82 for(unsigned int j = 0; j < point2CellPoints[i].size(); ++j) {
83 auto tup = point2CellPoints[i][j];
84 int const i0 = std::get<0>(tup);
85 int const i1 = std::get<1>(tup);
86
87 float p_i0[3], p_i1[3], p_i[3];
88 triangulation->getVertexPoint(i0, p_i0[0], p_i0[1], p_i0[2]);
89 triangulation->getVertexPoint(i1, p_i1[0], p_i1[1], p_i1[2]);
90 triangulation->getVertexPoint(i, p_i[0], p_i[1], p_i[2]);
91
92 double const dist_i_i0 = Geometry::distance(&p_i[0], &p_i0[0]);
93 double const dist_i_i1 = Geometry::distance(&p_i[0], &p_i1[0]);
94 double const dist_i0_i1 = Geometry::distance(&p_i0[0], &p_i1[0]);
95 double angleSurface;
97 dist_i_i0, dist_i_i1, dist_i0_i1, angleSurface);
98 sumAngleSurface += angleSurface;
99 if(distanceMatrix.size() != 0) {
100 double angleMetric;
101 double const distMat_i_i0 = distanceMatrix[i][i0];
102 double const distMat_i_i1 = distanceMatrix[i][i1];
103 double const distMat_i0_i1 = distanceMatrix[i0][i1];
105 distMat_i_i0, distMat_i_i1, distMat_i0_i1, angleMetric);
106 sumAngleMetric += angleMetric;
107 }
108 }
109
110 unsigned int const cornerNoCell = (noTriangle > noQuad ? 2 : 1);
111 double const coef
112 = (point2CellPoints[i].size() <= cornerNoCell
113 ? 0.5
114 : (triangulation->isVertexOnBoundary(i) ? 1 : 2));
115 surfaceCurvature[i] = coef * M_PI - sumAngleSurface;
116 // surfaceCurvature[i] *= std::pow(coef, -1);
117
118 if(distanceMatrix.size() != 0) {
119 metricCurvature[i] = coef * M_PI - sumAngleMetric;
120 // metricCurvature[i] *= std::pow(coef, -1);
121 diffCurvature[i] = metricCurvature[i] - surfaceCurvature[i];
122 }
123 }
124 }
125
126 void initIndicators(double &min, double &max, double &avg) {
127 min = std::numeric_limits<double>::max();
128 max = std::numeric_limits<double>::lowest();
129 avg = 0.0;
130 }
131
133 double &min, double &max, double &avg, double value, int noValue) {
134 min = std::min(min, value);
135 max = std::max(max, value);
136 avg += value / noValue;
137 }
138
139 template <class triangulationType, class tableDataType>
141 const triangulationType *triangulation,
142 std::vector<tableDataType *> &distanceMatrix,
143 std::vector<double> &surfaceDistance,
144 std::vector<double> &metricDistance,
145 std::vector<double> &ratioDistance,
146 std::vector<std::array<double, 3>> &surfacePointDistance,
147 std::vector<std::array<double, 3>> &metricPointDistance,
148 std::vector<std::array<double, 3>> &ratioPointDistance) {
149 unsigned int dim = triangulation->getNumberOfCells();
150 surfaceDistance = std::vector<double>(dim, std::nan(""));
151 metricDistance = std::vector<double>(dim, std::nan(""));
152 ratioDistance = std::vector<double>(dim, std::nan(""));
153#ifdef TTK_ENABLE_OPENMP
154#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_)
155#endif
156 for(unsigned int i = 0; i < dim; ++i) {
157 if(triangulation->getCellVertexNumber(i) != 2)
158 continue;
159
160 SimplexId i0, i1;
161 triangulation->getCellVertex(i, 0, i0);
162 triangulation->getCellVertex(i, 1, i1);
163
164 float p0[3], p1[3];
165 triangulation->getVertexPoint(i0, p0[0], p0[1], p0[2]);
166 triangulation->getVertexPoint(i1, p1[0], p1[1], p1[2]);
167
168 surfaceDistance[i] = Geometry::distance(&p0[0], &p1[0]);
169
170 if(distanceMatrix.size() != 0) {
171 metricDistance[i] = distanceMatrix[i0][i1];
172 ratioDistance[i] = metricDistance[i] / surfaceDistance[i];
173 }
174 }
175
176 dim = triangulation->getNumberOfVertices();
177 surfacePointDistance = std::vector<std::array<double, 3>>(dim);
178 metricPointDistance = std::vector<std::array<double, 3>>(dim);
179 ratioPointDistance = std::vector<std::array<double, 3>>(dim);
180#ifdef TTK_ENABLE_OPENMP
181#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_)
182#endif
183 for(unsigned int i = 0; i < dim; ++i) {
184 double minDistanceS, maxDistanceS, avgDistanceS;
185 initIndicators(minDistanceS, maxDistanceS, avgDistanceS);
186 double minDistanceM, maxDistanceM, avgDistanceM;
187 initIndicators(minDistanceM, maxDistanceM, avgDistanceM);
188
189 auto neighborNum = triangulation->getVertexNeighborNumber(i);
190 for(int j = 0; j < neighborNum; ++j) {
191 SimplexId neighbor;
192 triangulation->getVertexNeighbor(i, j, neighbor);
193
194 float p0[3], p1[3];
195 triangulation->getVertexPoint(i, p0[0], p0[1], p0[2]);
196 triangulation->getVertexPoint(neighbor, p1[0], p1[1], p1[2]);
197
198 double const distance = Geometry::distance(&p0[0], &p1[0]);
200 minDistanceS, maxDistanceS, avgDistanceS, distance, neighborNum);
201
202 if(distanceMatrix.size() != 0) {
203 double const distanceM = distanceMatrix[i][neighbor];
205 minDistanceM, maxDistanceM, avgDistanceM, distanceM, neighborNum);
206 }
207 }
208 surfacePointDistance[i][0] = minDistanceS;
209 surfacePointDistance[i][1] = maxDistanceS;
210 surfacePointDistance[i][2] = avgDistanceS;
211 if(distanceMatrix.size() != 0) {
212 metricPointDistance[i][0] = minDistanceM;
213 metricPointDistance[i][1] = maxDistanceM;
214 metricPointDistance[i][2] = avgDistanceM;
215 for(unsigned int j = 0; j < 3; ++j)
216 ratioPointDistance[i][j]
217 = metricPointDistance[i][j] / surfacePointDistance[i][j];
218 }
219 }
220 }
221
222 template <class triangulationType, class tableDataType>
223 void computeSurfaceArea(const triangulationType *triangulation,
224 std::vector<tableDataType *> &distanceMatrix,
225 std::vector<double> &surfaceArea,
226 std::vector<double> &metricArea,
227 std::vector<double> &ratioArea) {
228 unsigned int const dim = triangulation->getNumberOfCells();
229 surfaceArea = std::vector<double>(dim, std::nan(""));
230 metricArea = std::vector<double>(dim, std::nan(""));
231 ratioArea = std::vector<double>(dim, std::nan(""));
232#ifdef TTK_ENABLE_OPENMP
233#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_)
234#endif
235 for(unsigned int i = 0; i < dim; ++i) {
236 auto cellNoPoints = triangulation->getCellVertexNumber(i);
237 if(cellNoPoints < 3 or cellNoPoints > 4)
238 continue;
239
240 SimplexId i0, i1, i2;
241 triangulation->getCellVertex(i, 0, i0);
242 triangulation->getCellVertex(i, 1, i1);
243 triangulation->getCellVertex(i, 2, i2);
244
245 float p0[3], p1[3], p2[3];
246 triangulation->getVertexPoint(i0, p0[0], p0[1], p0[2]);
247 triangulation->getVertexPoint(i1, p1[0], p1[1], p1[2]);
248 triangulation->getVertexPoint(i2, p2[0], p2[1], p2[2]);
249
250 float area;
251 Geometry::computeTriangleArea(&p0[0], &p1[0], &p2[0], area);
252 surfaceArea[i] = area;
253
254 if(distanceMatrix.size() != 0) {
255 double areaMetric;
256 double const distMat_i0_i1 = distanceMatrix[i0][i1];
257 double const distMat_i1_i2 = distanceMatrix[i1][i2];
258 double const distMat_i2_i0 = distanceMatrix[i2][i0];
260 distMat_i0_i1, distMat_i1_i2, distMat_i2_i0, areaMetric);
261 metricArea[i] = areaMetric;
262 }
263
264 if(cellNoPoints == 4) {
265 SimplexId i3;
266 triangulation->getCellVertex(i, 3, i3);
267 float p3[3];
268 triangulation->getVertexPoint(i3, p3[0], p3[1], p3[2]);
269
270 float areaSurface;
271 Geometry::computeTriangleArea(&p1[0], &p2[0], &p3[0], areaSurface);
272 surfaceArea[i] += areaSurface;
273
274 if(distanceMatrix.size() != 0) {
275 double areaMetric;
276 double const distMat_i1_i2 = distanceMatrix[i1][i2];
277 double const distMat_i2_i3 = distanceMatrix[i2][i3];
278 double const distMat_i3_i1 = distanceMatrix[i3][i1];
280 distMat_i1_i2, distMat_i2_i3, distMat_i3_i1, areaMetric);
281 metricArea[i] += areaMetric;
282 }
283 }
284
285 if(distanceMatrix.size() != 0)
286 ratioArea[i] = metricArea[i] / surfaceArea[i];
287 }
288 }
289
290 }; // MetricDistortion class
291
292} // namespace ttk
#define M_PI
Definition Os.h:50
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
Minimalist debugging class.
Definition Debug.h:88
int preconditionTriangulation(AbstractTriangulation *triangulation)
void initIndicators(double &min, double &max, double &avg)
void updateIndicators(double &min, double &max, double &avg, double value, int noValue)
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)
int computeTriangleArea(const T *p0, const T *p1, const T *p2, T &area)
Definition Geometry.cpp:281
int computeTriangleAreaFromSides(const T s0, const T s1, const T s2, T &area)
Definition Geometry.cpp:296
int computeTriangleAngleFromSides(const T s0, const T s1, const T s2, T &angle)
Definition Geometry.cpp:321
T distance(const T *p0, const T *p1, const int &dimension=3)
Definition Geometry.cpp:362
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22