------------------------------------------------------------------------------ returns != 0 if vertex can be removed. Uses half-space comparison to determine whether ear-cut is valid, and may resort to line-plane intersections to resolve possible intersections with ear-cut.
| 1297 | // resort to line-plane intersections to resolve possible |
| 1298 | // intersections with ear-cut. |
| 1299 | int vtkPolyVertexList::CanRemoveVertex(vtkLocalPolyVertex* currentVtx) |
| 1300 | { |
| 1301 | double tolerance = this->Tol; |
| 1302 | int i, sign, currentSign; |
| 1303 | double v[3], sN[3], *sPt, val, s, t; |
| 1304 | vtkLocalPolyVertex *previous, *next, *vtx; |
| 1305 | |
| 1306 | // Check for simple case |
| 1307 | if (this->NumberOfVerts <= 3) |
| 1308 | { |
| 1309 | return 1; |
| 1310 | } |
| 1311 | |
| 1312 | // Compute split plane, the point to be cut off |
| 1313 | // is always on the positive side of the plane. |
| 1314 | previous = currentVtx->previous; |
| 1315 | next = currentVtx->next; |
| 1316 | |
| 1317 | sPt = previous->x; // point on plane |
| 1318 | for (i = 0; i < 3; i++) |
| 1319 | { |
| 1320 | v[i] = next->x[i] - previous->x[i]; // vector passing through point |
| 1321 | } |
| 1322 | |
| 1323 | vtkMath::Cross(v, this->Normal, sN); |
| 1324 | if ((vtkMath::Normalize(sN)) == 0.0) |
| 1325 | { |
| 1326 | return 0; // bad split, indeterminant |
| 1327 | } |
| 1328 | |
| 1329 | // Traverse the other points to see if a) they are all on the |
| 1330 | // other side of the plane; and if not b) whether they intersect |
| 1331 | // the split line. |
| 1332 | int oneNegative = 0; |
| 1333 | val = vtkPlane::Evaluate(sN, sPt, next->next->x); |
| 1334 | // NOLINTNEXTLINE(readability-avoid-nested-conditional-operator) |
| 1335 | currentSign = (val > tolerance ? 1 : (val < -tolerance ? -1 : 0)); |
| 1336 | oneNegative = (currentSign < 0 ? 1 : 0); // very important |
| 1337 | |
| 1338 | // Intersections are only computed when the split half-space is crossed |
| 1339 | for (vtx = next->next->next; vtx != previous; vtx = vtx->next) |
| 1340 | { |
| 1341 | val = vtkPlane::Evaluate(sN, sPt, vtx->x); |
| 1342 | // NOLINTNEXTLINE(readability-avoid-nested-conditional-operator) |
| 1343 | sign = (val > tolerance ? 1 : (val < -tolerance ? -1 : 0)); |
| 1344 | if (sign != currentSign) |
| 1345 | { |
| 1346 | if (!oneNegative) |
| 1347 | { |
| 1348 | oneNegative = (sign < 0 ? 1 : 0); // very important |
| 1349 | } |
| 1350 | if (vtkLine::Intersection( |
| 1351 | sPt, next->x, vtx->x, vtx->previous->x, s, t, tolerance, vtkLine::AbsoluteFuzzy) != 0) |
| 1352 | { |
| 1353 | return 0; |
| 1354 | } |
| 1355 | else |
| 1356 | { |
no test coverage detected