vtkCelllocator slow in the version VTK 9 than VTK 8

Hi,

I compare the performance of vtkCelllocator in vtk 9 compared to the VTK 8, I use FindClosestPoint method

I find that the VTK 9 is 2x more slow than VTK 8

Did some people identify the same problem ? What is the solution ?

Thks

Can you compare against the vtkStaticCellLocator ?

Yes, I tried it and I confirm that the vtkStaticCellLocator is very speed thant vtkCelllocator

But vtkStaticCellLocator not give the same result, see this topic and not solution is given
https://gitlab.kitware.com/vtk/vtk/-/issues/17911

FYI @will.schroeder @Charles_Gueunet

I’ll look into this if you provide data and a test please. Note the cell locators can and will give different results if there are two or more equivalent results, e.g., given a query point, two cells are within the exact same distance.

I re-use the case shared in the https://gitlab.kitware.com/vtk/vtk/-/issues/17911 topic

I re-adapt the code, and the sample must be called with Bunny.stl Sphere.stl in this order

VTK 8: Elapsed time (ms) = 63523
VTK 9: Elapsed time (ms) = 84815
35% more in VTK 9 than VTK 8.
My case with 2x time is more complex and I can’t share the data. But this example show this problem.

#include <iostream>
#include <string>
#include <chrono>
#include <vtkSTLReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkGenericCell.h>
#include <vtkCellLocator.h>

vtkSmartPointer<vtkPolyData> readSurfaceMeshStl(const std::string& filename)
{
   // Create STL reader
   const auto reader = vtkSmartPointer<vtkSTLReader>::New();
   reader->SetFileName(filename.c_str());
   reader->Update();

   // Get read surface mesh
   vtkSmartPointer<vtkPolyData> surfaceMesh = reader->GetOutput();

   return surfaceMesh;
}

int main(int argc, char** argv)
{
   auto start = std::chrono::system_clock::now();

   if (argc != 3)
   {
      cout << "Usage: ./testCellLocator interiorMeshStl boundingMeshStl" << endl;
      return EXIT_FAILURE;
   }

   std::string interiorMeshFileName = argv[1]; 
   std::string boundingMeshFileName = argv[2];

   std::cout << "Reading interior mesh...\n";
   vtkSmartPointer<vtkPolyData> interiorMesh = readSurfaceMeshStl(interiorMeshFileName);
   std::cout << "\nReading bounding mesh...\n";
   vtkSmartPointer<vtkPolyData> boundingMesh = readSurfaceMeshStl(boundingMeshFileName);

   const vtkIdType interiorMeshNumberOfPoints = interiorMesh->GetNumberOfPoints();

   // Octree
   auto boundingMeshLocator = vtkSmartPointer<vtkCellLocator>::New();
   boundingMeshLocator->SetDataSet(boundingMesh);
   boundingMeshLocator->BuildLocator();


   // Loop variables
   auto boundingMeshClosestCell = vtkSmartPointer<vtkGenericCell>::New();

   ///////////////////////////////////////////////////////////
   // Iterate through every vertex in the interior mesh
   ///////////////////////////////////////////////////////////
   double interiorMeshVertex[3];
   double closestBoundingMeshPoint[3];
   const int idMax(10);
   for (vtkIdType idx = 0; idx < idMax; ++idx)
   {
      for (vtkIdType i = 0; i < interiorMeshNumberOfPoints; ++i)
      {
         // Get point
         interiorMesh->GetPoint(i, interiorMeshVertex);

         // Find closest bounding mesh point
         vtkIdType boundingMeshClosestCellId = -1;
         int subId = -1;
         double dist = -1;
         boundingMeshLocator->FindClosestPoint(interiorMeshVertex, closestBoundingMeshPoint, boundingMeshClosestCell,
            boundingMeshClosestCellId, subId, dist);
      }
   }
   const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start);
   std::cout << "\nNbr of iterations = " << idMax << "\n";
   std::cout << "\nElapsed time (ms) = " << elapsed.count() << "\n";

   return EXIT_SUCCESS;
}

@Charles_Gueunet the sample help you to analyze the problem ?