0
$\begingroup$

I would need to translate a vtkCellLocator, without rebuilding it entirely. I suppose that it should be possible to apply an offset to all the buckets in the octree. Do you know if is it possible to do this (or to apply a translation to any other cell locator structure) with the tools already provided by vtk?

$\endgroup$

1 Answer 1

1
$\begingroup$

In order to translate a vtkCellLocator, you have only to translate a bounding box of root octant. However this bounding box cannot be publicly accessible. So it is necessary to create a new class inheriting from a vtkCellLocator and provide access functions to get and set it directly. The following is a simple example.

#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>

#include <vtkCellLocator.h>
#include <vtkObjectFactory.h>

class vtkMyCellLocator : public vtkCellLocator
{
public:
  static vtkMyCellLocator *New();

  vtkSetVectorMacro(Bounds,double,6);
  vtkGetVectorMacro(Bounds,double,6);
};
vtkStandardNewMacro(vtkMyCellLocator);

int main(int, char *[])
{
  auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->Update();

  // Create the tree
  auto cellLocator = vtkSmartPointer<vtkMyCellLocator>::New();
  cellLocator->SetDataSet(sphereSource->GetOutput());
  cellLocator->BuildLocator();

  double translate[3] = {10.0, 0, 0};
  auto transform = vtkSmartPointer<vtkTransform>::New();
  transform->Translate(translate);

  auto transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformFilter->SetTransform(transform);
  transformFilter->SetInputConnection(sphereSource->GetOutputPort());
  transformFilter->Update();
  cellLocator->SetDataSet(transformFilter->GetOutput());

  double bounds[6];
  cellLocator->GetBounds(bounds);
  for (int i = 0; i < 3; ++i)
  {
    bounds[2*i] += translate[i];
    bounds[2*i+1] += translate[i];
  }
  cellLocator->SetBounds(bounds);

  double testPoint[3] = {2.0, 0.0, 0.0};

  //Find the closest points to TestPoint
  double closestPoint[3];//the coordinates of the closest point will be returned here
  double closestPointDist2; //the squared distance to the closest point will be returned here
  vtkIdType cellId; //the cell id of the cell containing the closest point will be returned here
  int subId; //this is rarely used (in triangle strips only, I believe)
  cellLocator->FindClosestPoint(testPoint, closestPoint, cellId, subId, closestPointDist2);

  std::cout << "Coordinates of closest point: " << closestPoint[0] << " " << closestPoint[1] << " " << closestPoint[2] << std::endl;
  std::cout << "Squared distance to closest point: " << closestPointDist2 << std::endl;
  std::cout << "CellId: " << cellId << std::endl;

  return EXIT_SUCCESS;
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.