------------------------------------------------------------------------------ Different measures are supported. Historically, the measure was the ratio of triangle perimeter^2 to area (PERIMETER2_TO_AREA_RATIO). The other select for "best quality" triangles (BEST_QUALITY), and the largest dot product (DOT_PRODUCT - a measure of apex angle). The measure is used in a priority queue to select the
| 1218 | // positive numbers are selected first. Note that concave vertices, or zero |
| 1219 | // area vertices, return a negative measure. |
| 1220 | double vtkPolyVertexList::ComputeMeasure(vtkLocalPolyVertex* vtx) |
| 1221 | { |
| 1222 | double v1[3], v2[3], v3[3], v4[3], area, perimeter; |
| 1223 | |
| 1224 | for (int i = 0; i < 3; i++) |
| 1225 | { |
| 1226 | v1[i] = vtx->x[i] - vtx->previous->x[i]; |
| 1227 | v2[i] = vtx->next->x[i] - vtx->x[i]; |
| 1228 | v3[i] = vtx->previous->x[i] - vtx->next->x[i]; |
| 1229 | } |
| 1230 | vtkMath::Cross(v1, v2, v4); //|v4| is twice the area |
| 1231 | if ((area = vtkMath::Dot(v4, this->Normal)) < 0.0) |
| 1232 | { |
| 1233 | return (vtx->measure = -1.0); // concave or bad triangle |
| 1234 | } |
| 1235 | else if (area == 0.0) |
| 1236 | { |
| 1237 | return (vtx->measure = -VTK_DOUBLE_MAX); // concave or bad triangle |
| 1238 | } |
| 1239 | |
| 1240 | // If here, the vertex is convex and the area of the triangle is positive. |
| 1241 | // Compute the specified measure. |
| 1242 | if (this->Measure == vtkPolygon::PERIMETER2_TO_AREA_RATIO) |
| 1243 | { |
| 1244 | // This measure sucks as triangles become "needle-like" but works fine |
| 1245 | // when the triangle is more flattened. |
| 1246 | perimeter = vtkMath::Norm(v1) + vtkMath::Norm(v2) + vtkMath::Norm(v3); |
| 1247 | return (vtx->measure = perimeter * perimeter / area); |
| 1248 | } |
| 1249 | else if (this->Measure == vtkPolygon::DOT_PRODUCT) |
| 1250 | { |
| 1251 | vtkMath::Normalize(v1); |
| 1252 | vtkMath::Normalize(v2); |
| 1253 | return (vtx->measure = (1.0 + vtkMath::Dot(v1, v2))); |
| 1254 | } |
| 1255 | else if (this->Measure == vtkPolygon::BEST_QUALITY) |
| 1256 | { |
| 1257 | // Best quality: ratio of maximum edge length to height. |
| 1258 | // This is a greedy triangulation algorithm, so it may |
| 1259 | // not produce the mesh with the best total quality. However, |
| 1260 | // in greedy fashion it will select the next triangle with the |
| 1261 | // best quality. It is an expensive operation. |
| 1262 | double l1 = vtkMath::Norm(v1); |
| 1263 | double l2 = vtkMath::Norm(v2); |
| 1264 | double l3 = vtkMath::Norm(v3); |
| 1265 | // NOLINTNEXTLINE(readability-avoid-nested-conditional-operator) |
| 1266 | int longestEdge = (l1 > l2 ? (l1 > l3 ? 1 : 3) : (l2 > l3 ? 2 : 3)); |
| 1267 | double shortest, longest; |
| 1268 | if (longestEdge == 1) |
| 1269 | { |
| 1270 | longest = l1; |
| 1271 | shortest = vtkLine::DistanceToLine(vtx->next->x, vtx->x, vtx->previous->x); |
| 1272 | } |
| 1273 | else if (longestEdge == 2) |
| 1274 | { |
| 1275 | longest = l2; |
| 1276 | shortest = vtkLine::DistanceToLine(vtx->previous->x, vtx->x, vtx->next->x); |
| 1277 | } |
no test coverage detected