Hi VTK Community!
In the “Surface Picking” Trame example, found here, a user can “pick” locations on the screen and the closest point in the racecar mesh is selected and indicated with a cone pointer + tooltip. As far as I can tell, the mechanism for this feature is as follows: upon a “click” event, the event data are passed to
clickData, from which the
"world position" is extracted. The point closest to the “world position” coordinates is identified using the
FindPoint() method, and the dataset associated with that point is displayed in the tooltip.
I’d like to alter this example such that a cell is selected rather than a point. Intuitively, I reached for the
FindCell() method, but its use is much more complicated than I thought, as its performance seems to depend on many parameters (7 inputs compared to just 1 for
FindPoint()!). Given this complexity (for example, I’m not even sure how to pass an initialization cell to
FindCell()) I searched for an alternative. I’ve come across the
CellPicker() class which seems to be an efficient way to select a cell upon a click event. However, I can’t find a way to reset the picker used by the
vtkView() object (or would it be the
In summary, how might I adapt this example to make use of the
CellPicker class to efficiently select cells in a mesh?
As an aside, the cherry on top would be if someone could point to a reference that explains how the
vtkGeometryRepresentation() paradigm differs from, for example, the pipeline employed in the “Remote Selection” Trame example here.
So when doing selection with VtkView/VtkRepresentation, you are also getting a ray, which can be used for your FindCell.
virtual vtkIdType vtkDataSet::FindCell ( double x,
vtkCell * cell,
int & subId,
double * weights
Locate cell based on global coordinate x and tolerance squared.
If cell and cellId is non-nullptr, then search starts from this cell and looks at immediate neighbors. Returns cellId >= 0 if inside, < 0 otherwise. The parametric coordinates are provided in pcoords. The interpolation weights are returned in weights. (The number of weights is equal to the number of points in the found cell). Tolerance is used to control how close the point is to be considered “in” the cell. THIS METHOD IS NOT THREAD SAFE.
So the difference with VtkView/VtkRepresentation is that since the rendering is happening locally, you can get some xyz coord along with some ray in 3d and 2d (x,y) display coord. While for the RemoteView, you can only get the display (x,y) coordinate. You can still make your implementation only rely in 2d coords and let VTK/C++ do the ray/intersection.
Thank you for the help! While it’s still not quite clear how I would use a ray with
FindCell(), I was able to successfully use just the 3D coordinates (
FindCell(), as follows:
xyx = data["worldPosition"]
gen_cell = vtkGenericCell()
sub_id = reference(0)
pc = [0, 0, 0]
weights = [0,0,0,0,0,0,0,0,0,0,0,0]
face_idx = lines_polydata.FindCell(xyx, gen_cell, -1, 0.01, sub_id, pc, weights)
You can use a cell locator too like described here
Thank you @Sebastien_Jourdain! I’ve opted to use a
vtkCellPicker, as shown in this example from one of my other posts. I appreciate the suggestion!