How to pick a point closest from the mouse cursor?

Hi all.
I have a question about pick a point.

I have a commercial program that provides a function what if the mouse cursor moving, the closest point is selected.
It is useful when I zoom in the point cloud data and check the coordinate.
point pick

I made a sample program that checking the coordinate along with the mouse cursor.
I referred to the below link.
https://lorensen.github.io/VTKExamples/site/Cxx/Interaction/PointPicker/

I only can get the point’s coordinate when the cursor is above the point.

Does the VTK library provide the selecting the closest point from the mouse cursor?

I need your advise.

Thank you :slight_smile:

Hi, Kim,

I suggest you to take a look at https://vtk.org/doc/nightly/html/classvtkPointLocator.html and https://vtk.org/doc/nightly/html/classvtkCellLocator.html . Both have methods called FindClosestPoint*() and FindClosestCell*(). One should suit you.

regards,

Paulo

Hi, Paulo.
Thank you for your help.
But I have an additional question…

Do I need a preparation step to use the vtkPointLocator?

I have written the code that picking a point from the GetEventPosition() function on OnMouseMove() event.

I referred to the following examples:
https://lorensen.github.io/VTKExamples/site/Cxx/Interaction/Picking/
https://lorensen.github.io/VTKExamples/site/Cxx/Interaction/PointPicker/

I added the vtkPointLocator and call the FindClosestPoint() function, but it always returns -1.
I referred to the following examples:
https://lorensen.github.io/VTKExamples/site/Cxx/PolyData/PointLocator/
https://lorensen.github.io/VTKExamples/site/Cxx/PolyData/PointLocatorVisualization/

Could you please advise for me?

Thank you.

Best regards,
William Kim

Hello, can you post the part of your code involved in point search?

regards,

Paulo

Hi Paulo.

I have modified my code and it doesn’t return -1 but it doesn’t work well.

I attached the code part of the mouse event, if you can review my code I can send you my full code.

virtual void OnMouseMove() override
{
	if (m_bEnablePicking == true)
	{
		int* pos = this->GetInteractor()->GetEventPosition();
			
		vtkNew<vtkPropPicker> picker;
		picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());
		double* worldPosition = picker->GetPickPosition();
			
		int id = locator_point->FindClosestPoint(pos[0], pos[1], pos[2]);
		double* position = polydata->GetPoint(id);
	}

	vtkInteractorStyleTrackballCamera::OnMouseMove();
}

vtkSmartPointer<vtkPointLocator> locator_point;

Thank you.

Best regards,
William Kim

Hello, Kim,

Try changing your pick handling code to something like this (notice the vtkPointPicker in place of vtkPropPicker):

// Get pick position in 2D screen coordinates.
int* clickPos = this->GetInteractor()->GetEventPosition();

// Get the point of a 3D object under the 2D screen coordinates (ray casting).
vtkSmartPointer<vtkPointPicker>  pointPicker = vtkSmartPointer<vtkPointPicker>::New();
pointPicker->Pick(clickPos[0], clickPos[1], 0, this->GetDefaultRenderer());

//if a point was picked...
if( pointPicker->GetPointId() != -1 ) {

      // ...get the picked location in world coordinates.
      double* pos = picker->GetPickPosition();

      // Get the picked vertex.
      int id = locator_point->FindClosestPoint(pos[0], pos[1], pos[2]);
      double* position = polydata->GetPoint(id);
     
      (...)

} else {
      std::cout << "Pick failed." << std::endl;
}

I hope this helps,

Paulo

Taking a second look, I think you can stick with the vtkPropPicker. So, can you paste the part of the code where you instantiate and configure locator_point?

Hi Paulo.

I attached my code as below:

vtkNew<vtkPoints> m_vtkPCDPoints;
vtkNew<vtkPolyData> m_vtkPolydata;
vtkNew<vtkUnsignedCharArray> colors;

//...
m_vtkPolydata->SetPoints(m_vtkPCDPoints);
m_vtkPolydata->GetPointData()->SetScalars(colors);
m_vtkPointLocator->SetDataSet(m_vtkPolydata);
//...

Thank you.

Hi Paulo.

oh… The vtkPointPicker works better than vtkPropPicker.

I think it is fine. Thank you.

May I ask you to review my code that written above comment?

Hi, Kim,

Do polydata and m_vtkPolydata in your examples point to the same object? If not, you can’t use point IDs of one object to fetch points of another data set. The IDs are like indexes in a container.

all the best,

Paulo

Hi Paulo.

Thank you for your kindly help.

I solved my issue by your advise.

Thank you :slight_smile:

Best regards,
William Kim

1 Like