Is there any way to to determine which actor is clicked when using vtkCellPicker to pick a assembly.

Hello,for some reasons I have to put a bunch of actors into an assembly and at the same I have to highlight picked clicked.But

vtkCellPicker->GetViewProp()

returns a vtkAssembly?My questions are:

1, Is there any way to to determine which actor is clicked within this assembly?

If not,I found vtkCellPicker->GetCellId() will return a cell id,

2, Is there any way to detemine the actor that this cell id belongs to?

I am not an expert. I am not sure if you have already tried looking into vtkAssemblyPath. Here is an excerpt from “The VTK User’s Guide” 11th Edition pag 59:

The class vtkAbstractProp-
Picker is another direct subclass of vtkAbstractPicker. It defines an API for pickers that can pick an
instance of vtkProp. There are several convenience methods in this class to allow querying for the
return type of a pick.
• GetProp() — Return the instance of vtkProp that was picked. If anything at all was picked,
then this method will return a pointer to the instance of vtkProp, otherwise NULL is returned.
• GetProp3D() — If an instance of vtkProp3D was picked, return a pointer to the instance of
vtkProp3D.
• GetActor2D() — If an instance of vtkActor2D was picked, return a pointer to the instance of
vtkActor2D.
• GetActor() — If an instance of vtkActor was picked, return a pointer to the instance of
vtkActor.
60 The Basics
• GetVolume() — If an instance of vtkVolume was picked, return a pointer to the instance of
vtkVolume.
• GetAssembly() — If an instance of vtkAssembly was picked, return a pointer to the instance*
of vtkAssembly.
• GetPropAssembly() — If an instance of vtkPropAssembly was picked, return a pointer to the*
instance of vtkPropAssembly.
A word of caution about these methods. The class (and its subclass) return information about the top
level of the assembly path that was picked. So if you have an assembly whose top level is of type
vtkAssembly, and whose leaf node is of type vtkActor, the method GetAssembly() will return a
pointer to the instance of vtkAssembly, while the GetActor() method will return a NULL pointer (i.e.,
*no vtkActor). If you have a complex scene that includes assemblies, actors, and other types of props,
the safest course to take is to use the GetProp() method to determine whether anything at all was
picked, and then use GetPath()

at pag 61:

vtkAssemblyPath
An understanding of the class vtkAssemblyPath is essential if you are to perform picking in a scene
with different types of vtkProp’s, especially if the scene contains instances of vtkAssembly. vtkAs-
semblyPath is simply an ordered list of vtkAssemblyNode’s, where each node contains a pointer to a
vtkProp, as well as an optional vtkMatrix4x4. The order of the list is important: the start of the list
represents the root, or top level node in an assembly hierarchy, while the end of the list represents a
leaf node in an assembly hierarchy. The ordering of the nodes also affects the associated matrix. Each
matrix is a concatenation of the node’s vtkProp’s matrix with the previous matrix in the list. Thus, for
a given vtkAssemblyNode, the associated vtkMatrix4x4 represents the position and orientation of the
vtkProp (assuming that the vtkProp is initially untransformed).

and most importantly read here (from vtkAbstractPropPicker Class Reference):

vtkAbstractPropPicker is an abstract superclass for pickers that can pick an instance of vtkProp. Some pickers, like vtkWorldPointPicker (not a subclass of this class), cannot identify the prop that is picked. Subclasses of vtkAbstractPropPicker return a prop in the form of a vtkAssemblyPath when a pick is invoked. Note that an vtkAssemblyPath contain a list of vtkAssemblyNodes, each of which in turn contains a reference to a vtkProp and a 4x4 transformation matrix. The path fully describes the entire pick path, so you can pick assemblies or portions of assemblies, or just grab the tail end of the vtkAssemblyPath (which is the picked prop).

2 Likes

Thanks, with your tips I found the solution:

auto assemblyPath = m_cellPicker->GetPath();
if (!assemblyPath)
{
return;
}
auto actor = vtkActor::SafeDownCast(assemblyPath->GetLastNode()->GetViewProp());
std::cout << "actor = " << actor << std::endl;

1 Like