// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkCellLocator.h" #include "vtkCellTreeLocator.h" #include "vtkGenericCell.h" #include "vtkIdList.h" #include "vtkNew.h" #include "vtkPolyData.h" #include "vtkStaticCellLocator.h" #include "vtkTestUtilities.h" #include "vtkXMLPolyDataReader.h" #include static bool TestCell(vtkDataSet* ds, vtkIdType cellId, double x1[3], double x2[3], double tol) { double t = 0.0; double x[3] = { 0.0, 0.0, 0.0 }; double pcoords[3] = { 0.0, 0.0, 0.0 }; int subId = 0; vtkNew cell; ds->GetCell(cellId, cell); return static_cast(cell->IntersectWithLine(x1, x2, tol, t, x, pcoords, subId)); } static bool TestLocator(vtkDataSet* ds, vtkAbstractCellLocator* loc) { std::cout << "\nTesting " << loc->GetClassName() << std::endl; loc->SetDataSet(ds); loc->CacheCellBoundsOn(); loc->AutomaticOn(); loc->BuildLocator(); vtkNew cell; vtkNew cellList; double t = 0.0; double x[3] = { 0.0, 0.0, 0.0 }; double pcoords[3] = { 0.0, 0.0, 0.0 }; int subId = 0; vtkIdType cellId = -1; double tol = 1.0e-15; double x1[3] = { 0.437783024586950, 0.0263950841209563, 0.373722994626027 }; double x2[3] = { 0.442140196830658, 0.0256207765183134, 0.374080391702881 }; // This IntersectWithLine returns the intersected cell with the smallest parametric t. bool foundIntersectWithLineBest = false; loc->IntersectWithLine(x1, x2, tol, t, x, pcoords, subId, cellId, cell); if (cellId != -1) { std::cout << "IntersectWithLineBest: " << cellId << std::endl; foundIntersectWithLineBest = TestCell(ds, cellId, x1, x2, tol); } // This IntersectWithLine returns all the cells that intersected with the line bool foundIntersectWithLineAll = false; loc->IntersectWithLine(x1, x2, tol, nullptr, cellList, cell); for (vtkIdType i = 0; i < cellList->GetNumberOfIds(); ++i) { std::cout << "IntersectWithLineAll: " << cellList->GetId(i) << std::endl; foundIntersectWithLineAll |= TestCell(ds, cellList->GetId(i), x1, x2, tol); } // This FindCellAlongLine (which is actually the above version without passing a cell) // returns all the cells that their bounds intersected with the line bool foundFindCellAlongLine = false; loc->FindCellsAlongLine(x1, x2, tol, cellList); for (vtkIdType i = 0; i < cellList->GetNumberOfIds(); ++i) { std::cout << "FindCellAlongLine: " << cellList->GetId(i) << std::endl; foundFindCellAlongLine |= TestCell(ds, cellList->GetId(i), x1, x2, tol); } return foundIntersectWithLineBest && foundIntersectWithLineAll && foundFindCellAlongLine; } static bool TestCellLocatorEvaluatePosition(char* fname) { vtkNew poly_reader; poly_reader->SetFileName(fname); poly_reader->Update(); vtkNew loc; loc->SetDataSet(poly_reader->GetOutput()); loc->CacheCellBoundsOn(); loc->SetNumberOfCellsPerNode(2); loc->BuildLocator(); double test_point[] = { -5.091451e-02, -1.800857e-01, 1.153756e+00 }; // expected result constexpr double dist_exp = 1.658136e-01; constexpr double closest_point_exp[] = { -1.582647e-01, -5.475835e-01, 1.015066e+00 }; constexpr int cell_id_exp = 1944; // threshold for floating point checking constexpr double thresh = 1e-5; constexpr double radius = 0.5; double closest_point[3]; vtkIdType cell_id; int sub_id, inside; double dist; vtkNew cell; loc->FindClosestPointWithinRadius( test_point, radius, closest_point, cell, cell_id, sub_id, dist, inside); if (fabs(dist - dist_exp) / fabs(dist_exp) < thresh && fabs(closest_point[0] - closest_point_exp[0]) / fabs(closest_point_exp[0]) < thresh && fabs(closest_point[1] - closest_point_exp[1]) / fabs(closest_point_exp[1]) < thresh && fabs(closest_point[2] - closest_point_exp[2]) / fabs(closest_point_exp[2]) < thresh && cell_id == cell_id_exp) return true; return false; } int TestCellLocatorsEdgeCases(int argc, char* argv[]) { //=========== // Test Setup //=========== vtkNew reader; char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/test_surface.vtp"); reader->SetFileName(fname); reader->Update(); vtkDataSet* data = reader->GetOutput(); bool allTestsPassed = true; vtkNew cl; allTestsPassed &= TestLocator(data, cl); vtkNew scl; allTestsPassed &= TestLocator(data, scl); vtkNew ctl; allTestsPassed &= TestLocator(data, ctl); // can't test vtkModifiedBSPTree because of the peculiarities // of how this test is executed // vtkNew mbsp; // allTestsPassed &= TestLocator(data, mbsp); allTestsPassed &= TestCellLocatorEvaluatePosition( vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/cone.vtp")); //==================== // Final Tests Outcome //==================== return allTestsPassed ? EXIT_SUCCESS : EXIT_FAILURE; }