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 vtkGeometryRepresentation()
object?).
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 vtkView()
+ 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[3],
vtkCell * cell,
vtkIdType cellId,
double tol2,
int & subId,
double pcoords[3],
double * weights
)
pure virtual
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[3]. 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.
HTH,
Seb
Hi Sebastien,
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 ("worldPosition"
) with 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!
1 Like